我基本上有一个文件夹中所有文件的列表,简化版本如下:
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']
另一个清单:
drug_list = [ '17A', '96A', '56B']
我想将这两个列表组合成一个字典,例如:
dictionary = {
'17A' : ['drug.resp1.17A.tag' , 'drug.resp2.17A.tag' ],
'96A' : ['drug.resp1.96A.tag' , 'drug.resp2.96A.tag' ],
'56B' : ['drug.resp1.56B.tag' , 'drug.resp2.56B.tag' ]}
我想这样做却被卡住了!
dict_drugs = {}
for file in file_list:
list_filename = file.split('.')
for elem in drug_list:
if elem in list_filename:
在此之后我可以做什么才能将元素加入字典中,或者我完全错误了?
答案 0 :(得分:5)
你不需要内循环
>>> 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']
>>> dictonary = {}
... for i in file_list:
... k = i.split('.')[-2]
... if k in dictonary:
... dictonary[k].append(i)
... else:
... dictonary[k] = [i]
>>> dictonary
62: {'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']}
>>>
再检查一下是否只需要drug_list中存在的那些值
表示file_list包含:
file_list = [' drug.resp1.18A.tag ','drug.resp1.96A.tag','drug.resp1.56B.tag','drug.resp2.17A。 tag','drug.resp2.56B.tag','drug.resp2.96A.tag']
>>> drug_list = [ '17A', '96A', '56B']
... dictonary = {}
... for i in file_list:
... k = i.split('.')[-2]
... if k in drug_list:
... if k in dictonary:
... dictonary[k].append(i)
... else:
... dictonary[k] = [i]
>>>
另一种有效做大写的方法:
dictonary = dict(((i,[]) for i in drug_list))
dictonary = {drug: [] for drug in drug_list} # As @J.F. Sebastian suggested.
for file in file_list:
k = file.split('.')[-2]
if k in dictonary:
dictonary[k].append(file)
答案 1 :(得分:3)
假设所有文件在药物清单中都有相应的匹配:
dic = {d:[] for d in drug_list}
for file in file_list: dic[file.split('.')[-2]].append(file)
答案 2 :(得分:3)
您可以尝试使用itertools
和groupby
(有关详细信息,请参阅here),其目标是提供用于“分组”的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
来有效地仅包含您set
中找到的药物,if a in b
仅包含唯一项目并且具有O的好处(1)查找(意思是说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']}
不需要搜索整个对象,如列表的情况):
{{1}}
答案 3 :(得分:1)
试试这个:
dict_drugs = {s:[] for s in drug_list}
for file in file_list:
list_filename = file.split('.')
for elem in list_filename:
if elem in drug_list:
dict_drugs[elem].append(file)
我更改了支票的顺序,因此它会搜索字典中的部分文件名而不是文件名中的药物。
另外,请注意,字典在开头时已初始化,每个药物都有一个空列表。
答案 4 :(得分:1)
您可以使用2个推理来自然地循环数据结构。
dict((drug, [file for file in file_list if drug in file]) for drug in drug_list)
让我们打破这个。我们需要创建一个字典,所以让我们使用列表理解。
dict((a, str(a + " is the value")) for a in [1, 2, 3])
最外面的部分是创建一个字典的列表理解。通过创建表单(键,值)的2元组,我们可以简单地在其上调用dict()来获取字典。在我们的回答中,我们将药物设置为关键,并将值设置为从另一个列表理解构建的列表。到目前为止,我们有:
{'17A': [SOMETHING],
'56B': [SOMETHING],
'96A': [SOMETHING]}
现在我们需要填写SOMETHING,这就是内心理解的作用。看起来您的逻辑是检查药物文本是否出现在文件中。我们已经有了这种药物,所以我们可以说:
[file for file in file_list if drug in file]
这会在文件列表中运行,并在药物出现时将其添加。
在Python 2.7及更高版本中,您可以使用字典理解而不是使用dict()。在这种情况下,它看起来像:
{drug: [file for file in file_list if drug in file] for drug in drug_list}
这更加清晰,因为制作2元组和转换的所有锅炉板都可以完成。
理解是编写代码的一种很好的方式,因为它往往非常清楚地描述了你的意思。值得注意的是,这不是构建字典的最有效方式,因为它贯穿每种药物的每个文件。如果文件列表很长,则可能非常慢。
编辑:我的第一个回答是胡说八道。作为忏悔,我已经详细说明了这一点。
答案 5 :(得分:1)
itertools.ifilter
可以将其变为单行词典理解。
>>> from itertools import ifilter
>>> 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']
>>> drug_list = [ '17A', '96A', '56B']
>>> { k: list( ifilter( lambda v: k in v, file_list ) ) for k in drug_list }
{
'56B': ['drug.resp1.56B.tag', 'drug.resp2.56B.tag'],
'96A': ['drug.resp1.96A.tag', 'drug.resp2.96A.tag'],
'17A': ['drug.resp1.17A.tag', 'drug.resp2.17A.tag']
}
答案 6 :(得分:1)
如果药物清单中的字符串始终是文件列表中字符串的子字符串,则可以使用三个简单的代码行来完成。
In [1]: d = {}
In [2]: for drug in drug_list:
....: d[drug] = [file for file in file_list if drug in file]
In [3]: d
Out[3]:
{'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']}
答案 7 :(得分:1)
尽量使问题尽可能简单:
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']
drug_list = [ '17A', '96A', '56B']
result = {}
for drug in drug_list:
result[drug] = []
for file_name in file_list:
if drug in file_name:
result[drug].append(file_name)
答案 8 :(得分:0)
这似乎有效
import re
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']
drug_list = [ '17A', '96A', '56B']
drugIdRegex = re.compile(r"drug\.resp\d+\.(?P<drugId>\d+\w+)\.tag")
if __name__ == "__main__":
results = dict.fromkeys(drug_list, None)
for file_name in file_list:
matcher = drugIdRegex.match(file_name)
if matcher and matcher.group("drugId") in results:
if results[matcher.group("drugId")] is None:
results[matcher.group("drugId")] = list()
results[matcher.group("drugId")].append(file_name)
print "Results: %s" % results
虽然我很确定你可以用一行中的列表推导来做到这一点!!那很酷(但我不知道怎么样):)
答案 9 :(得分:0)
python 3.2
{i:[v for v in file_list if i in v] for i in drug_list}
答案 10 :(得分:0)
问题是您不知道药物的数量,未来可能会有新的药物。
我真的很喜欢法鲁克的答案,几乎是我的思维方式,但我会把它添加到drug_list创作中。
drug_list = list(set([x.split('.')[-2] for x in file_list]))