Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何迭代嵌套的dict(计数器)并递归更新键_Python_Dictionary_Counter - Fatal编程技术网

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