Python 如何迭代嵌套的dict(计数器)并递归更新键
我正在将文件中的数据读取到一系列列表中,如下所示:Python 如何迭代嵌套的dict(计数器)并递归更新键,python,dictionary,counter,Python,Dictionary,Counter,我正在将文件中的数据读取到一系列列表中,如下所示: sourceData = [[source, topic, score],[source, topic, score],[source, topic, score]...] 其中,每个列表中的源和主题可以相同或不同 我试图实现的是一个字典,它将与每个源相关的主题进行分组,并将它们的相关分数进行平均,但出于这个问题的目的,让我们将它们列为主题键的值 理想情况下,结果将类似于嵌套dict的列表,如下所示: [{SOURCE1:{TOPIC_A:S
sourceData = [[source, topic, score],[source, topic, score],[source, topic, score]...]
其中,每个列表中的源和主题可以相同或不同
我试图实现的是一个字典,它将与每个源相关的主题进行分组,并将它们的相关分数进行平均,但出于这个问题的目的,让我们将它们列为主题键的值
理想情况下,结果将类似于嵌套dict的列表,如下所示:
[{SOURCE1:{TOPIC_A:SCORE1,SCORE2,SCORE3},
{TOPIC_B:SCORE1,SCORE2,SCORE3},
{TOPIC_C:SCORE1,SCORE2,SCORE3}},
{SOURCE2:{TOPIC_A:SCORE1,SCORE2,SCORE3},
{TOPIC_B:SCORE1,SCORE2,SCORE3},
{TOPIC_C:SCORE1,SCORE2,SCORE3}}...]
我认为最好的方法是创建一个源代码计数器,然后为每个源代码的每个主题创建一个dict,并将每个dict保存为每个对应源代码的值。但是,我在正确迭代以获得所需结果时遇到困难
以下是我目前掌握的情况:
sourceDict = {}
sourceDictList = []
for row in sourceData:
source = row[0]
score = row[1]
topic = row[2]
sourceDict = [source,{topic:score}]
sourceDictList.append(sourceDict)
sourceList.append(source)
其中,sourceDictList产生以下结果:[[source,{topic:score}]…],本质上是从最初的列表列表重新格式化数据,而sourceList只是一个包含所有重复的源的列表
然后我初始化一个计数器,并将计数器中的源与sourceDictList中的源进行匹配,如果匹配,则将主题:score dict保存为键:
sourceCounter = Counter(sourceList)
for key,val in sourceCounter.items():
for dictitem in sourceDictList:
if dictitem[0] == key:
sourceCounter[key] = dictitem[1]
但是输出只保存了最后一个主题:对每个源进行评分。因此,不是期望的:
[{SOURCE1:{TOPIC_A:SCORE1,SCORE2,SCORE3},
{TOPIC_B:SCORE1,SCORE2,SCORE3},
{TOPIC_C:SCORE1,SCORE2,SCORE3}},
{SOURCE2:{TOPIC_A:SCORE1,SCORE2,SCORE3},
{TOPIC_B:SCORE1,SCORE2,SCORE3},
{TOPIC_C:SCORE1,SCORE2,SCORE3}}...]
我只得到:
Counter({SOURCE1: {TOPIC_n: 'SCORE_n'}, SOURCE2: {TOPIC_n: 'SCORE_n'}, SOURCE3: {TOPIC_n: 'SCORE_n'}})
我的印象是,如果有一个唯一的键保存到dict中,它将附加该键:值对,而不会覆盖以前的键对。我错过什么了吗
非常感谢您在这方面的帮助。我们可以:
sourceData = [
['source1', 'topic1', 'score1'],
['source1', 'topic2', 'score1'],
['source1', 'topic1', 'score2'],
['source2', 'topic1', 'score1'],
['source2', 'topic2', 'score2'],
['source2', 'topic1', 'score3'],
]
sourceDict = {}
for row in sourceData:
source = row[0]
topic = row[1]
score = row[2]
if source not in sourceDict:
# This will be executed when the source
# comes for the first time.
sourceDict[source] = {}
if topic not in sourceDict[source]:
# This will be executed when the topic
# inside that source comes for the first time.
sourceDict[source][topic] = []
sourceDict[source][topic].append(score)
print(sourceDict)
您只需使用集合的defaultdict即可
sourdata = [['source', 'topic', 2],['source', 'topic', 3], ['source', 'topic2', 3],['source2', 'topic', 4]]
from collections import defaultdict
sourceDict = defaultdict(dict)
for source, topic, score in sourdata:
topicScoreDict = sourceDict[source]
topicScoreDict[topic] = topicScoreDict.get(topic, []) + [score]
>>> print(sourceDict)
>>> defaultdict(<class 'dict'>, {'source': {'topic': [2, 3], 'topic2': [3]}, 'source2': {'topic': [4]}})
>>> print(dict(sourceDict))
>>> {'source': {'topic': [2, 3], 'topic2': [3]}, 'source2': {'topic': [4]}}
作品介意解释一下这两个if语句吗?谢谢。抱歉迟到了。我会尽快澄清,只要我有时间。补充了两条评论。请检查!完美的评论说得很清楚,但实际上,经过几秒钟的思考,这一点也很明显:3