您可以尝试使用itertools
and groupby
(有关更多信息,请参阅此处),其目标是提供一个key
值,用于“分组”您的file_list
(请注意,该sorted
部分是必要的,因为项目需要按排序顺序正确分组) :
In [1]: from itertools import groupby
In [2]: file_list = [ 'drug.resp1.17A.tag', 'drug.resp1.96A.tag', 'drug.resp1.56B.tag', 'drug.resp2.17A.tag', 'drug.resp2.56B.tag', 'drug.resp2.96A.tag']
In [3]: drug_list = [ '17A', '96A', '56B']
In [4]: grouper = lambda x: x.split('.')[-2]
In [5]: d = {}
In [6]: for key, group in groupby(sorted(file_list, key=grouper), key=grouper):
...: d[key] = list(group)
...:
...:
In [7]: d
Out[7]:
{'17A': ['drug.resp1.17A.tag', 'drug.resp2.17A.tag'],
'56B': ['drug.resp1.56B.tag', 'drug.resp2.56B.tag'],
'96A': ['drug.resp1.96A.tag', 'drug.resp2.96A.tag']}
这样做是在拆分后按倒数第二个元素对您的每个项目进行file_list
分组,然后将结果组分配给在该位置找到的键。部分是为了grouper
节省一点空间 - 因为我们将通过我们的特殊键对列表进行排序,然后使用该lambda
函数按相同的键进行分组,我们只是将该函数存储在一个单独的变量中,以便该groupby
子句更易于阅读.
需要注意的一件事是,这不取决于您的drug_list
,这可能对您很重要,也可能不重要。例如,这会将类似的东西分组drug.resp1.1000A.tag
到1000A
组中。
正如@JFSebastian 所提到的,您可以drug_list
通过将列表转换为 a来有效地仅包含在您的列表中找到的那些药物set
,这将仅包含唯一的项目,并且具有 O(1) 查找的好处(这意味着if a in b
不需要搜索整个对象,与列表一样):
In [10]: drug_list = set(drug_list)
In [11]: only_listed = (f for f in file_list if grouper(f) in drug_list)
In [12]: only_listed
Out[12]: <generator object <genexpr> at 0x24fcbe0>
In [13]: for key, group in groupby(sorted(only_listed, key=grouper), key=grouper):
....: d[key] = list(group)
....:
....:
In [14]: d
Out[14]:
{'17A': ['drug.resp1.17A.tag', 'drug.resp2.17A.tag'],
'56B': ['drug.resp1.56B.tag', 'drug.resp2.56B.tag'],
'96A': ['drug.resp1.96A.tag', 'drug.resp2.96A.tag']}