如何迭代嵌套的dict(计数器)并递归地更新键

2024-10-03 23:19:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在将文件中的数据读入一系列列表,如下所示:

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中的源代码进行匹配,如果匹配,则将topic:scoredict保存为键:

sourceCounter = Counter(sourceList)


for key,val in sourceCounter.items():
    for dictitem in sourceDictList:
        if dictitem[0] == key:
            sourceCounter[key] = dictitem[1]            

但是输出只是将最后的topic:scoredict保存到每个源。因此,不是期望的:

[{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中保存了一个唯一的密钥,它将附加key:value对,而不会覆盖以前的密钥。我错过什么了吗?你知道吗

谢谢你的帮助。你知道吗


Tags: keysource主题列表topic源代码dictrow
2条回答

您可以简单地使用集合的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]}}

我们可以做到:

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)

相关问题 更多 >