2013-03-05 41 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']}