2012-02-27 67 views
5

比方说,我有文件排序文件

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

的名单,我需要将它们整理到基于了他们的数量,使

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

我可以写子列表一堆循环,但我想知道是否有更好的方法来做到这一点?

+1

已经由数量排序的文件列表,因为它似乎是在这个例子中? – 2012-02-27 13:45:06

+0

没有不幸的。 – John 2012-02-27 13:45:50

+4

你想要的是*分组*,*不*排序。 – 2012-02-27 13:46:35

回答

6

这里是基于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) 

这将产生:

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

真正伟大的答案,它的工作真的很好,因为我在做什么。 – John 2012-02-27 15:57:47

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我也把一个例子密钥生成函数,如'拉姆达X:应用re.sub( '[^ 0-9]', '',X)'。 – 2012-02-27 13:50:14

+3

这个答案错误地假定列表已经按数量排序。 – 2012-02-27 13:50:44

+0

在的问题是:) – 2012-02-27 13:54:40

1

首先,写一个从文件名中提取数的函数:(请注意,此功能将错误是否有在名称中没有数在所有)

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

排序使用此功能作为一个键列表:

files.sort(key=file_number) 

集团通过此键10:

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

像这样的工作..

#!/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) 

请注意,依赖定的顺序,你会在列表内获得名单,但你可以折叠那些很轻松了..

输出示例:

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