0

我有以下两个要合并到字典中的数组:

# Input:
wrd = ['i', 'am', 'am', 'the', 'boss', 'the', 'tiger', 'eats', 'rice', 'eats', 'grass']
cnt = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Output: 
{
    'i': [0],
    'am': [1,2],
    'the': [3,5],
    'boss': [4],
    'tiger': [6],
    'eats': [7,9],
    'rice': [8],
    'grass': [10]
}

我尝试了以下代码,但我认为我的想法引导我走错了路:

    dict={}
    j=0
    for i in wrd:
        if i in dict:
           dict[i].insert(cnt[j])
        else:
           dict[i].append(cnt[j])
           j+=1

    v=dict.values()
    k=dict.keys()
    for k,v in dict.items():
         print k,v

由于我是 python 的新手,我承认我在这里缺乏知识。

4

3 回答 3

3

在这里使用collections.defaultdict。见片段

>>> wrd=['i','am','am','the','boss','the','tiger','eats','rice','eats','grass']
>>> cnt=[0,1,2,3,4,5,6,7,8,9,10]
>>> from collections import defaultdict
>>> a = defaultdict(list)
>>> for key, val in zip(wrd, cnt): # Preferably for val, key in enumerate(wrd):
        a[key].append(val)


>>> a
defaultdict(<type 'list'>, {'grass': [10], 'i': [0], 'am': [1, 2], 'eats': [7, 9], 'boss': [4], 'tiger': [6], 'the': [3, 5], 'rice': [8]})
>>> a['am']
[1, 2]
>>> a['the']
[3, 5]
于 2013-08-01T18:21:56.770 回答
3

为工作使用正确的工具(这里,defaultdict,如 Sukrit Kalra 的回答)始终是最好的解决方案。但了解您的尝试出了什么问题也很有用。

if i in dict:
   dict[i].insert(cnt[j])
else:
   dict[i].append(cnt[j])
   j+=1

如果i已经在 中dict,那很好:dict[i]是一个列表,您将调用insert它。那是行不通的,只是因为insert需要两个参数——插入对象的索引和要插入的对象。只需将其更改为append(cnt[j]), 或insert(0, cnt[j]), 或任何合适的。

但是,如果i它还没有在 中dict,那么你正在尝试append一些不存在的东西。那显然行不通。您必须先创建 alist并将其放入,dict[i]然后才能对dict[i]. 因此,您可以将该行更改为:

    dict[i] = [cnt[j]]

......这将解决它。

一旦你理解了这一点,你就有希望理解为什么 Sukrit Kalra 的答案如此酷: a只是defaultdictadict自动为任何不存在的键创建默认值。所以,你可以只写,不管它是否已经存在,它都可以工作。dict[i].append(cnt[j])dict[i]


作为旁注,命名 dictdict是一个坏主意,因为它隐藏了同名的内置类和构造函数。

更一般地说,使用更好的名称总是有帮助的。你用神秘的缩写和一个字母的名字保存的击键将被你浪费在调试代码和向需要寻求帮助的人解释的击键所抵消。将输入称为wordsand counts、外部循环变量wordj计数器count_index等。

同时:cnt几乎完全没用。对于任何不超过 10 的数字,它cnt[j]j,对于任何超过 10 的数字,它是一个IndexError。为什么不直接使用j

于 2013-08-01T18:24:28.717 回答
1

您无需创建计数器列表。Enumerate 会为你做这件事:

list(enumerate(['i','am','am','the','boss','the','tiger','eats','rice','eats','grass']))
#=> [(0, 'i'), (1, 'am'), (2, 'am'), (3, 'the'), (4, 'boss'), (5, 'the'), (6, 'tiger'), (7, 'eats'), (8, 'rice'), (9, 'eats'), (10, 'grass')]

现在,您可以使用 defaultdict 收集它们:

collect = defaultdict(list)
for idx, wrd in enumerate(['i','am','am','the','boss','the','tiger','eats','rice','eats','grass']):
    collect[wrd].append(idx)

但是,真正的问题是你为什么需要这个。您打算如何处理这些索引回到原始列表中?

于 2013-08-01T18:25:41.087 回答