2013-03-05 117 views
1

有没有办法可以使用list comprehension answered in this thread创建词典?Python:创建词典与多列表理解

listA = [ 
    "apple_v001", 
    "apple_v002", 
    "banana_v001", 
    "orange_v001", 
] 
keywords = ["apple", "banana", "orange"] 
[[item for item in listA if kw in item] for kw in keywords] 
# Result: [['apple_v001', 'apple_v002'], ['banana_v001'], ['orange_v001']] # 

我想要做的是创建一个字典使用关键字作为这个结果的关键。所以

dictA["apple"] = ['apple_v001', 'apple_v002'] 

等等。我试图做dict = {key,值...(迭代)},但总是得到一个语法错误。我真的不知道如何开始,任何帮助表示赞赏。

+2

为什么是'标签的python-2.7'如果你使用'蟒蛇-2.6'? – jfs 2013-03-05 04:39:47

回答

2
{kw: [item for item in listA if kw in item] for kw in keywords} 

但这似乎并不是一个特别有效的方式来创建这样一个字典

例如,这并不需要关键字列表提前,是合理有效

>>> from itertools import groupby 
>>> {k:list(g) for k,g in groupby(sorted(listA), key=lambda x:x.partition('_')[0])} 
{'orange': ['orange_v001'], 'apple': ['apple_v001', 'apple_v002'], 'banana': ['banana_v001']} 

对于Python2.6而言,相当于

dict((kw, [item for item in listA if kw in item]) for kw in keywords) 

>>> from itertools import groupby 
>>> dict((k,list(g)) for k,g in groupby(sorted(listA), key=lambda x:x.partition('_')[0])) 
{'orange': ['orange_v001'], 'apple': ['apple_v001', 'apple_v002'], 'banana': ['banana_v001']} 
+0

非常有趣。谢谢你给我看。这是特定于Python 3吗?因为我使用Python 2.6有语法错误。 – Panupat 2013-03-05 04:31:27

+0

@Panupat,2.7+。我将为2.6添加一条注释到答案 – 2013-03-05 12:43:00

2

如果你不想去一个班轮解决方案,检查此

In [58]: d 
Out[58]: defaultdict(<type 'list'>, {}) 

In [59]: for elem in keywords: 
    ....:  for item in listA: 
    ....:   if item.startswith(elem): 
    ....:    d[elem].append(item) 
    ....: 

In [60]: d 
Out[60]: defaultdict(<type 'list'>, {'orange': ['orange_v001'], 'apple': ['apple_v001', 'apple_v002'], 'banana': ['banana_v001']}) 
+0

这段代码比上面的一行更容易阅读! – JesseBikman 2013-03-05 04:39:32

1

In the comments you mentioned that you use Python 2.6。在Python 2.6无字典理解,你可以使用dict()与发电机expresion代替:

d = dict((kw, [item for item in listA if kw in item]) for kw in keywords) 

这里有一个可能更有效的版本:

import re 
from collections import defaultdict 

search_word = re.compile("(%s)" % "|".join(map(re.escape, keywords))).search 

d = defaultdict(list) 
for item in listA: 
    m = search_word(item) 
    if m: 
     d[m.group(1)].append(item) 

如果listA总是在给定的格式问题:

from collections import defaultdict 

keywords = set(keywords) 
d = defaultdict(list) 
for item in listA: 
    word = item.partition("_")[0] 
    if word in keywords: 
     d[word].append(item) 

如果listA不包含不在keywords项目:

from collections import defaultdict 

d = defaultdict(list) 
for item in listA: 
    d[item.partition('_')[0]].append(item) 
0

您可以使用正则表达式:

>>> import re 
>>> listA = [ 
...  "apple_v001", 
...  "apple_v002", 
...  "banana_v001", 
...  "orange_v001", 
... ] 
>>> keywords = ["apple", "banana", "orange"] 
>>> s=' '.join(listA) 
>>> dict([(e,re.findall(r'{}_v\d+'.format(e),s)) for e in keywords]) 
{'orange': ['orange_v001'], 'apple': ['apple_v001', 'apple_v002'], 'banana': ['banana_v001']} 

或(后Python 2.7版)的字典理解:

>>> {e:re.findall(r'{}_v\d+'.format(e),s) for e in keywords} 
{'orange': ['orange_v001'], 'apple': ['apple_v001', 'apple_v002'], 'banana': ['banana_v001']}