字典在for循环中只返回最后一组键值对

3

我有一个字符串列表,如下:

A = [
    'philadelphia court excessive disappointed court hope hope',
    'hope hope jurisdiction obscures acquittal court',
    'mention hope maryland signal held mention problem internal reform life bolster level grievance'
    ]

还有另一个列表如下:

B = ['court', 'hope', 'mention', 'life', 'bolster', 'internal', 'level']

我想基于字符串列表 A 中单词列表 B 的出现次数创建字典。就像这样:

C = [
        {'count':2,'hope':2,'mention':0,'life':0,'bolster':0,'internal':0,'level':0},
        {'count':1,'hope':2,'mention':0,'life':0,'bolster':0,'internal':0,'level':0},
        {'count':0,'hope':1,'mention':2,'life':1,'bolster':1,'internal':1,'level':1}
    ]

我喜欢的是,

dic={}
for i in A:
    t=i.split()
    for j in B:
        dic[j]=t.count(j)

但是,它只返回字典的最后一对键值对。

print(dic)

{'court': 0,
 'hope': 1,
 'mention': 2,
 'life': 1,
 'bolster': 1,
 'internal': 1,
 'level': 1}

“我想创建字典”实际上是不正确的,你正在尝试创建一个字典列表。因此需要将字典附加到列表中。还要注意在哪里初始化dic。请检查我的答案。 - FatihAkici
你可以使用collections.Counter来代替手动计数,从而稍微改进你的代码。 - Blckknght
5个回答

2

与您示例输出中创建字典列表不同,您仅创建了一个字典(并在检查短语时每次覆盖单词计数)。可以使用re.findall来计算每个短语中单词的出现次数(这样做的好处是如果任何短语包含带有标点符号的单词(如“hope?”),它不会失败)。

最初的回答

import re

words = ['court', 'hope', 'mention', 'life', 'bolster', 'internal', 'level']
phrases = ['philadelphia court excessive disappointed court hope hope','hope hope jurisdiction obscures acquittal court','mention hope maryland signal held mention problem internal reform life bolster level grievance']

counts = [{w: len(re.findall(r'\b{}\b'.format(w), p)) for w in words} for p in phrases]

print(counts)
# [{'court': 2, 'hope': 2, 'mention': 0, 'life': 0, 'bolster': 0, 'internal': 0, 'level': 0}, {'court': 1, 'hope': 2, 'mention': 0, 'life': 0, 'bolster': 0, 'internal': 0, 'level': 0}, {'court': 0, 'hope': 1, 'mention': 2, 'life': 1, 'bolster': 1, 'internal': 1, 'level': 1}]

1

两个问题:您正在错误地初始化dic,并且没有将这些dic收集到列表中。以下是修复方法:

C = []    
for i in A:
    dic = {}
    t=i.split()
    for j in B:
        dic[j]=t.count(j)
    C.append(dic)
# Result:
[{'court': 2, 'hope': 2, 'mention': 0, 'life': 0, 'bolster': 0, 'internal': 0, 'level': 0},
{'court': 1, 'hope': 2, 'mention': 0, 'life': 0, 'bolster': 0, 'internal': 0, 'level': 0},
{'court': 0, 'hope': 1, 'mention': 2, 'life': 1, 'bolster': 1, 'internal': 1, 'level': 1}]

1
@学习者 当然可以!请不要忘记接受最有帮助的答案。谢谢! - FatihAkici
1
是的,我一定会做。只是想问一下,我有一个大约有10万个字符串的列表,使用for循环会增加计算时间吗? - Learner
@Learner 既然你必须对两个列表上的每个元素进行迭代,而且没有例外,我认为双重循环是不可避免的。 - FatihAkici
是的,我已经使用了你的代码。计算结果花费了很长时间。你有更好的方法吗?这将非常有帮助。 - Learner
@学习者 请了解一下Python中的并行处理-多线程。这样,您可以将作业分成多个部分并并行运行,从而显著缩短时间。 - FatihAkici

0

试试这个,

from collections import Counter

A = ['philadelphia court excessive disappointed court hope hope',
     'hope hope jurisdiction obscures acquittal court',
     'mention hope maryland signal held mention problem internal reform life bolster level grievance']

B = ['court', 'hope', 'mention', 'life', 'bolster', 'internal', 'level']

result = [{b: dict(Counter(i.split())).get(b, 0) for b in B} for i in A]
print(result)

输出:

[{'court': 2, 'hope': 2, 'mention': 0, 'life': 0, 'bolster': 0, 'internal': 0, 'level': 0}, {'court': 1, 'hope': 2, 'mention': 0, 'life': 0, 'bolster': 0, 'internal': 0, 'level': 0}, {'court': 0, 'hope': 1, 'mention': 2, 'life': 1, 'bolster': 1, 'internal': 1, 'level': 1}]

0

你总是用 dict[j]=t.count(j) 覆盖字典 dic 中已有的值。你可以为每个 i 创建一个新的字典,并将其附加到列表中,例如:

dic=[]
for i in A:
    i_dict = {}
    t=i.split()
    for j in B:
        i_dict[j]=t.count(j)
    dic.append(i_dict)
print(dic)

0
为避免覆盖现有值,请检查该条目是否已经存在于字典中。尝试添加以下内容:
if j in b:
    dic[j] += t.count(j)
else:
    dic[j] = t.count(j)

我做了一些事情,dic=[] for i in A: i_dict = {} t=i.split() for j in B: if j in t: i_dict[j] += t.count(j) else: i_dict[j] = t.count(j) dic.append(i_dict) 出现错误 KeyError: 'court' - Learner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接