我们说这个类型有很长的清单:
text = [ ['a', 'b'], ['a', 'd'], ['w', 'a'], ['a', 'b'], ... ]
鉴于第一个元素,我想构建一个显示第二个元素计数的字典。例如,在上面的特定示例中,我希望有类似这样的内容:
{'a': {'b':2, 'd':1},
'w': {'a':1}
}
这是我试图解决它的方法失败了。我构建了一个独特的第一个元素列表。我们称之为words
然后:
dic = {}
for word in words:
inner_dic = {}
for pair in text:
if pair[0] == word:
num = text.count(pair)
inner_dic[pair[1]] = num
dic[pair[0]] = inner_dic
我得到一个明显错误的结果。代码的一个问题是,它覆盖了对。我不知道如何解决这个问题。
答案 0 :(得分:5)
您可以使用defaultdict结合Counter dict:
from collections import Counter, defaultdict
d = defaultdict(Counter)
text = [ ['a', 'b'], ['a', 'd'], ['w', 'a'], ['a', 'b'] ]
for k, v in text:
d[k][v] += 1 # for single value
# d[k].update(v) for multiple values i.e list of words
from pprint import pprint as pp
pp(d)
{'a': Counter({'b': 2, 'd': 1}),
'w': Counter({'a': 1})}
defaultdict将创建一个新的键/值配对,其中值为Counter dict,如果键不存在,如果键存在,我们只使用Counter.update更新值,这与dict.update不同,将增加值覆盖。
使用正常的dict
没有导入,我们可以使用dict.setdefault,这会为每个键k
创建一个新的dict,并设置默认值0
每个子项v
:
d = {}
text = [ ['a', 'b'], ['a', 'd'], ['w', 'a'], ['a', 'b'] ]
for k, v in text:
d.setdefault(k, {}).setdefault(v,0)
d[k][v] += 1
pp(d)
{'a': {'b': 2, 'd': 1}, 'w': {'a': 1}}
答案 1 :(得分:5)
collections module简化了这样的任务。
对计数部分使用Counter(它是一种字典,对于缺失值返回0,使得+=1
用于递增计数变得容易)。使用defaultdict作为外部字典(它可以自动为每个“第一个”前缀创建一个新计数器):
>>> from collections import defaultdict, Counter
>>> d = defaultdict(Counter)
>>> text = [ ['a', 'b'], ['a', 'd'], ['w', 'a'], ['a', 'b']]
>>> for first, second in text:
d[first][second] += 1
以下是使用常规词典的等效词:
text = [ ['a', 'b'], ['a', 'd'], ['w', 'a'], ['a', 'b']]
d = {}
for first, second in text:
if first not in d:
d[first] = {}
inner_dict = d[first]
if second not in inner_dict:
inner_dict[second] = 0
inner_dict[second] += 1
短路或长路可以与json module完美配合(计数器和 defaultdict 是可以进行JSON编码的各种类型的dicts)
希望这会有所帮助。祝你的文字分析好运: - )
答案 2 :(得分:4)
你应该这样做:
for word in words:
inner_dic = {}
for pair in text:
if pair[0] == word:
num = text.count(pair)
inner_dic[pair[1]] = num
dic[word] = inner_dic
也就是说,您应该dic[word]
而不是dic[pair[0]]
,这会将inner_dic
分配给最后pair
次检查的第一个元素,即使pair[0]
也是如此word
1}}不是{{1}}。
答案 3 :(得分:1)
以下是使用.setdefault方法的方法:
text = [ ['a', 'b'], ['a', 'd'], ['w', 'a'], ['a', 'b'] ]
result={}
for x, y in text:
result.setdefault(x, {}).setdefault(y,0)
result[x][y]+=1
>>> result
{'a': {'b': 2, 'd': 1}, 'w': {'a': 1}}
无需外部资源库。
答案 4 :(得分:0)
text = [ ['a', 'b'], ['a', 'd'], ['w', 'a'], ['a', 'b']]
d = {}
for i in text:
if d.get(i[0]):
if d[i[0]].get(i[1]):
d[i[0]][i[1]] +=1
else:
d[i[0]][i[1]] = 1
else:
d[i[0]] = {i[1] : 1}
print d
>>>{'a': {'b': 2, 'd': 1}, 'w': {'a': 1}}