Python:如何查找文件列表中最常见的元素

Python:如何查找文件列表中最常见的元素,python,optimization,coding-style,Python,Optimization,Coding Style,首先,对于这个简单的问题,我很抱歉,但是我想不出编写问题代码的最简单方法 我有一个目录,其中有几个不同的文件,但有共同的元素(值_25、_26、_28等),如下所示: 我希望获得以下列表: xxxxx_25.txt yyyyy_25.txt mmmmm_25.txt xxxxx_26.txt yyyyy_26.txt mmmmm_26.txt xxxxx_27.txt yyyyy_27.txt mmmmm_27.txt xxxxx_28.txt yyyyy_29.txt mmmmm_3

首先,对于这个简单的问题,我很抱歉,但是我想不出编写问题代码的最简单方法

我有一个目录,其中有几个不同的文件,但有共同的元素(值_25、_26、_28等),如下所示:

我希望获得以下列表:

xxxxx_25.txt
yyyyy_25.txt
mmmmm_25.txt

xxxxx_26.txt
yyyyy_26.txt
mmmmm_26.txt

xxxxx_27.txt
yyyyy_27.txt
mmmmm_27.txt

xxxxx_28.txt

yyyyy_29.txt

mmmmm_30.txt
get\u number\u和\u prefix
返回的元组将首先按数字排序,然后按前缀排序

相反,如果您想根据文件名中的数字进行分组,可以使用以下方法:

def update_dict_with_file(dict_, filename):
    g = re.match('.*(\d+)', filename)
    key = g.group(1)
    t = dict_.setdefault(key,[])
    t.append(filename)

mydict = {}
[update_dict_with_file(mydict, filename) 
 for filename in list_with_file_names]
mydict
现在包含文件名中的数字作为键,列表中的文件名作为值

编辑

要总结到目前为止的所有答案,您所需要的只是从列表中构建一个
排序的
列表,使用一个key getter函数从文件名中提取您想要的内容。您可以通过使用
itertools
+列表理解的奇特的一行程序,或者使用更长的
for
循环(无
产生
任何地方?)。但是,基本上,它们都是一样的。没有火箭科学。

这样就可以了:

list_of_files = [
    'xxxxx_25.txt',
    'xxxxx_26.txt',
    'xxxxx_27.txt',
    'xxxxx_28.txt',
    'yyyyy_25.txt',
    'yyyyy_26.txt',
    'yyyyy_27.txt',
    'yyyyy_29.txt',
    'mmmmm_25.txt',
    'mmmmm_26.txt',
    'mmmmm_27.txt',
    'mmmmm_30.txt',
    ]

import re
regex = re.compile('_([0-9]+)\.txt$')

def keyfn(name):
    match = regex.search(name)
    if match is None:
        return None
    else:
        return match.group(1)

import itertools
for (key, group) in itertools.groupby(sorted(list_of_files,key=keyfn),keyfn):
    print [x for x in group]
或者,如果需要列表列表,请将循环替换为:

[x for g in itertools.groupby(sorted(list_of_files,key=keyfn),keyfn) for x in g[1]]
对于这项任务,使用非常方便

In [1]: import re; from collections import defaultdict

In [2]: filenames
Out[2]: 
['xxxxx_25.txt',
 'xxxxx_26.txt',
 'xxxxx_27.txt',
 'xxxxx_28.txt',
 'yyyyy_25.txt',
 'yyyyy_26.txt',
 'yyyyy_27.txt',
 'yyyyy_29.txt',
 'mmmmm_25.txt',
 'mmmmm_26.txt',
 'mmmmm_27.txt',
 'mmmmm_30.txt']

In [3]: d = defaultdict(list)

In [4]: for filename in filenames:
  ....:     m = re.search(r'_(\d+)\.txt$', filename)
  ....:     if m:
  ....:         d[m.group(1)].append(filename)

In [5]: [sorted(filename_list) for filename_list in d.values()]
Out[5]: 
[['xxxxx_25.txt', 'yyyyy_25.txt'],
 ['mmmmm_26.txt', 'xxxxx_26.txt', 'yyyyy_26.txt'],
 ['mmmmm_27.txt', 'yyyyy_27.txt'],
 ['xxxxx_28.txt'],
 ['yyyyy_29.txt'],
 ['mmmmm_30.txt']]

我不确定这是不是定义得很好——为什么不根据它们都以
.txt
结尾这一事实对它们进行分组?@Gianni:下次,请准确地指定您希望输出的内容-我不知道您是否需要平面列表或嵌套列表,前缀的顺序是否重要等等。。
[x for g in itertools.groupby(sorted(list_of_files,key=keyfn),keyfn) for x in g[1]]
#Considering your list of files is as follows
ur_file_list = """xxxxx_25.txt
xxxxx_26.txt
xxxxx_27.txt
xxxxx_28.txt
yyyyy_25.txt
yyyyy_26.txt
yyyyy_27.txt
yyyyy_29.txt
mmmmm_25.txt
mmmmm_26.txt
mmmmm_27.txt
mmmmm_30.txt"""
#Based on the pattern, you can get the key assuming, you need the part in the
#filename (without ext) after underscore. So this will give you the part without regex
key = lambda e: os.path.splitext(e)[0].split("_")[-1]
from itertools import groupby
#On a sorted list, group on the above key function
#And generate a list of these groups
[list(group) for _, group in groupby(sorted(ur_file_list.splitlines(), key = key), key = key)]
[['xxxxx_25.txt', 'yyyyy_25.txt', 'mmmmm_25.txt'], ['xxxxx_26.txt', 'yyyyy_26.txt', 'mmmmm_26.txt'], ['xxxxx_27.txt', 'yyyyy_27.txt', 'mmmmm_27.txt'], ['xxxxx_28.txt'], ['yyyyy_29.txt'], ['mmmmm_30.txt']]
In [1]: import re; from collections import defaultdict

In [2]: filenames
Out[2]: 
['xxxxx_25.txt',
 'xxxxx_26.txt',
 'xxxxx_27.txt',
 'xxxxx_28.txt',
 'yyyyy_25.txt',
 'yyyyy_26.txt',
 'yyyyy_27.txt',
 'yyyyy_29.txt',
 'mmmmm_25.txt',
 'mmmmm_26.txt',
 'mmmmm_27.txt',
 'mmmmm_30.txt']

In [3]: d = defaultdict(list)

In [4]: for filename in filenames:
  ....:     m = re.search(r'_(\d+)\.txt$', filename)
  ....:     if m:
  ....:         d[m.group(1)].append(filename)

In [5]: [sorted(filename_list) for filename_list in d.values()]
Out[5]: 
[['xxxxx_25.txt', 'yyyyy_25.txt'],
 ['mmmmm_26.txt', 'xxxxx_26.txt', 'yyyyy_26.txt'],
 ['mmmmm_27.txt', 'yyyyy_27.txt'],
 ['xxxxx_28.txt'],
 ['yyyyy_29.txt'],
 ['mmmmm_30.txt']]