【问题标题】:Adding nested dictionaries in Python from yield从 yield 在 Python 中添加嵌套字典
【发布时间】:2016-12-10 20:38:16
【问题描述】:

如果我这样做:

x1={'Count': 11, 'Name': 'Andrew'}
x2={'Count': 14, 'Name': 'Matt'}
x3={'Count': 17, 'Name': 'Devin'}
x4={'Count': 20, 'Name': 'Andrew'}
x1

vars=[x1,x2,x3,x4]
for i in vars:
    my_dict[i[group_by_column]]=i
my_dict

然后我得到:

defaultdict(int,
            {'Andrew': {'Count': 20, 'Name': 'Andrew'},
             'Devin': {'Count': 17, 'Name': 'Devin'},
             'Geoff': {'Count': 10, 'Name': 'Geoff'},
             'Matt': {'Count': 14, 'Name': 'Matt'}})

这正是我想要的。

但是,当我尝试从内置 yield 的对象中复制它时,它会不断覆盖字典中的非常值。例如,cast_record_stream 是一个函数结果,可根据要求生成以下字典:

{'Count': 11, 'Name': 'Andrew'}
{'Count': 14, 'Name': 'Matt'}
{'Count': 17, 'Name': 'Devin'}
{'Count': 20, 'Name': 'Andrew'}
{'Count': 5, 'Name': 'Geoff'}
{'Count': 10, 'Name': 'Geoff'}

那么当我运行这个函数时,它就出现了错误:

for line in cast_record_stream:
    record_name=line['Name']
    my_dict[record_name]=line

    defaultdict(<type 'int'>, {'Devin': {'Count': 10, 'Name': 'Geoff'}, 
'Matt': {'Count': 10, 'Name': 'Geoff'}, 
'Geoff': {'Count': 10, 'Name': 'Geoff'}, 
'Andrew': {'Count': 10, 'Name': 'Geoff'}})

我是否在这里制造了一个我看不到的问题?我认为它一次只会添加一个值。

【问题讨论】:

  • 使用相关的yield 显示您的代码可能会有所帮助。
  • 它是多个函数链接在一起,所以它只会让人感到困惑。重要的部分是它产生了我上面列出的每个字典,其中一些有重复的Name
  • 我的猜测:cast_record_stream 修改并再次生成 相同 字典。确保在屈服之前创建一个新的字典。
  • 不,如果我在调用最后一个循环后添加一行print line,它将在每次迭代时生成不同的字典。
  • 它会打印一个“不同”(看起来)的字典,因为您在打印之前没有更改它们。发布您的生成器函数,我大约 99.7% 确定这是问题所在。

标签: python dictionary nested


【解决方案1】:

我无法重现您的问题。这是一个完整的复制品,除了它完美无缺。这表明您在OP中描述的想法是正确的,并且您在实际代码中还有其他一些错误。

cast_list = [
    {'Count': 11, 'Name': 'Andrew'},
    {'Count': 14, 'Name': 'Matt'},
    {'Count': 17, 'Name': 'Devin'},
    {'Count': 20, 'Name': 'Andrew'},
    {'Count': 5, 'Name': 'Geoff'},
    {'Count': 10, 'Name': 'Geoff'},
]

def cast_record_stream():
    for record in cast_list:
        yield record

from collections import defaultdict
d = {}
for record in cast_record_stream():
    print record
    d[record['Name']] = record
print d

根据下面 cmets 中的讨论,我认为您有时会存储 record_name=line['Name'] ,但有时它不会更新,因为您正在迭代不应该的东西,可能会导致 for 循环永远不会执行更新记录名称的行。

【讨论】:

  • 所以我正在尝试这个但它不起作用.....它不能将cast_record_stream 识别为一个函数,因为在我的代码中它是一个存储上一个函数中的yield 的对象
  • 我虽然你说它是一个生成器函数。如果这是一个产量,那么你不能迭代它。您只需添加一个产量,现在就完成了。在其他地方有一个迭代(否则有一个生成器会很愚蠢),这就是你可以构建完整字典的地方。
  • 我不确定我是否关注,抱歉。我是 python 新手,我只能说 cast_recode_stream 不是一个函数,而是存储前一个函数的 yield 结果。我不想发布所有内容,因为这是针对某事的培训,我担心隐私问题。
  • 如果是这样,那么你正在迭代的不是你认为你正在迭代的。当您跳过那部分代码时,在调试器中查看它。
  • 我(想)我理解yield 的作用,那么我如何以可迭代的方式获取它生成的每个对象并将其存储在字典中?
【解决方案2】:

几个问题。首先,我假设 cast_record_stream 是一个函数,所以你的第一行应该是

for line in cast_record_stream():

字典不能有重复的键。如果您的迭代器返回两个 Geoff,则后者将始终覆盖前者。如果您希望有重复的名称,您可能应该考虑使用与字典不同的方法来存储数据。

R

【讨论】:

  • 这是一个包含所有单独字典的函数结果,但由于yield 部分,这些字典一次出现一个
  • 请注意'Devin': {'Count': 10, 'Name': 'Geoff'} 中的键与字典中的名称有何不同。 dicts 以正确的(不同的)名称从生成器中出来,但在打印之前它们都被更改了。同样,我的猜测是这些都指向同一个 dict 实例。
猜你喜欢
  • 2018-04-25
  • 2018-11-07
  • 2016-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-14
相关资源
最近更新 更多