2012-02-27 12 views
5

Digamos que tengo una lista de archivosClasificación de archivos en una lista

files = ['s1.txt', 'ai1.txt', 's2.txt', 'ai3.txt'] 

y necesito que los clasifique en sublistas con sede fuera de su número para que

files = [['s1.txt', 'ai1.txt'], ['s2.txt'], ['ai3.txt']] 

podría escribir un montón de bucles, sin embargo, me pregunto si hay una mejor manera de hacerlo.

+1

la lista de archivos ya ordenados según número, ya que parece ser en el ejemplo? –

+0

no desafortunadamente. – John

+4

Lo que quiere es * agrupamiento *, no * clasificación *. –

Respuesta

6

que aquí hay una, ejemplo de trabajo completo basado en defaultdict:

import re 
from collections import defaultdict 

files = ['s1.txt', 'ai1.txt', 's2.txt', 'ai3.txt'] 

def get_key(fname): 
    return int(re.findall(r'\d+', fname)[0]) 

d = defaultdict(list) 
for f in files: 
    d[get_key(f)].append(f) 

out = [d[k] for k in sorted(d.keys())] 
print(out) 

Esto produce:

[['s1.txt', 'ai1.txt'], ['s2.txt'], ['ai3.txt']] 
+0

Muy buena respuesta, funcionó muy bien para lo que estaba haciendo. – John

4
import itertools 
import re 

r_number = re.compile("^.*([0-9]+).*$") 

def key_for_filename(filename): 
    # Edit: This doesn't check for missing numbers. 
    return r_number.match(filename).group(1) 

grouped = [list(v) for k, v in 
      itertools.groupby(sorted(files, key=key_for_filename), 
          key_for_filename)] 
+0

+1 También pondría una función de generación de claves de ejemplo, como 'lambda x: re.sub ('[^ 0-9]', '', x)'. –

+3

Esta respuesta asume erróneamente que la lista ya está ordenada por número. –

+0

En la pregunta es :) –

1

En primer lugar, escribir una función que extrae el número de un nombre de archivo: (. Tenga en cuenta que esta función de error si no hay ningún número en el nombre)

def file_number(name): 
    return re.search(r"\d+", "s1.txt").group(0) 

ordenar la lista mediante esta función como una tecla:

files.sort(key=file_number) 

Grupo por esta clave usando itertools.groupby():

for number, group in itertools.groupby(files, file_number): 
    # whatever 
0

Algo como esto iba a funcionar ..

#!/usr/bin/python 

from itertools import groupby 
import re 
import pprint 

def findGroup(record): 
    return re.match(".*?(\d+).txt$", record).group(1) 

files = [ 's1.txt', 'ai1.txt', 's2.txt', 'ai3.txt', 'foo1.txt', 'foo54.txt' ] 

results = {} 
for k,g in groupby(files, findGroup): 
    if not results.has_key(k): 
     results[k] = [] 
    results[k].append([x for x in g]) 

pprint.pprint(results) 

Nota, esa dependencia ding del orden, obtendrá listas dentro de listas, pero se puede colapsar fácilmente aquellos lo suficientemente ..

Ejemplo de salida:

{'1': [['s1.txt', 'ai1.txt'], ['foo1.txt']], 
'2': [['s2.txt']], 
'3': [['ai3.txt']], 
'54': [['foo54.txt']]} 
Cuestiones relacionadas