在成对列表中查找成对项目的频率
finding frequencies of pair items in a list of pairs
假设我有一长串这种类型的清单:
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
我得到了一个明显错误的结果。代码的一个问题是,它多算了对。我不确定如何解决这个问题。
您可以使用 defaultdict combined with a Counter 字典:
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 将创建一个新的 key/value 配对,如果键不存在,值为计数器字典,如果键存在,我们只需使用 Counter.update 更新值,这与 dict.update 将增加不覆盖的值。
使用没有导入的普通 dict
我们可以使用 dict.setdefault 这将为每个键创建一个新的字典作为值 k
并设置默认值 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}}
collections module 可以缩短此类任务的完成时间。
对外部字典使用Counter for the counting part (it is a kind of dictionary that returns 0 for missing values, making it easy to use +=1
for incrementing counts). Use defaultdict(它可以自动为每个"first"前缀创建一个新计数器):
>>> 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 完美配合(Counter 和 defaultdict 都是种类可以 JSON 编码的字典数)。
希望这对您有所帮助。祝你的文本分析顺利:-)
你应该这样做:
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
.
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}}
这里有一个使用.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}}
不需要外部库。
假设我有一长串这种类型的清单:
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
我得到了一个明显错误的结果。代码的一个问题是,它多算了对。我不确定如何解决这个问题。
您可以使用 defaultdict combined with a Counter 字典:
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 将创建一个新的 key/value 配对,如果键不存在,值为计数器字典,如果键存在,我们只需使用 Counter.update 更新值,这与 dict.update 将增加不覆盖的值。
使用没有导入的普通 dict
我们可以使用 dict.setdefault 这将为每个键创建一个新的字典作为值 k
并设置默认值 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}}
collections module 可以缩短此类任务的完成时间。
对外部字典使用Counter for the counting part (it is a kind of dictionary that returns 0 for missing values, making it easy to use +=1
for incrementing counts). Use defaultdict(它可以自动为每个"first"前缀创建一个新计数器):
>>> 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 完美配合(Counter 和 defaultdict 都是种类可以 JSON 编码的字典数)。
希望这对您有所帮助。祝你的文本分析顺利:-)
你应该这样做:
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
.
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}}
这里有一个使用.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}}
不需要外部库。