【问题标题】:How to keep the dictionary up to date when using a generator?使用生成器时如何使字典保持最新?
【发布时间】:2017-11-02 07:49:34
【问题描述】:

当我使用生成器时,即使我修改了传递给它的字典,生成器仍然给我一个旧数据结构的结果。 我该如何解决这个问题?

def min_key_order(adict:dict):
    for key, value in sorted(adict.items()):
        yield (key, value)

d = {1:'a', 2:'x', 4:'m', 8:'d', 16:'f'}
i = min_key_order(d)
print(next(i))
d.pop(2)
print(next(i))

它给了我(1,'a')(2,'x'),即使我有字典中的弹出键 2。

【问题讨论】:

  • 您不能遍历您更改的字典。这是不受支持的行为。
  • 但是,sorted() 函数会生成一个新列表;该列表不会随着原始词典的变化而更新。
  • 这些都与生成器无关,如果将 d.pop() 放在 for 循环中 sorted(d) 上,则会得到相同的行为。

标签: python dictionary generator


【解决方案1】:

您的生成器没有遍历字典。它正在迭代 sorted() 返回的新列表对象:

>>> d = {1:'a', 2:'x', 4:'m', 8:'d', 16:'f'}
>>> l = sorted(d.items())
>>> d
{1: 'a', 2: 'x', 4: 'm', 8: 'd', 16: 'f'}
>>> l
[(1, 'a'), (2, 'x'), (4, 'm'), (8, 'd'), (16, 'f')]
>>> d.pop(2)
'x'
>>> l
[(1, 'a'), (2, 'x'), (4, 'm'), (8, 'd'), (16, 'f')]

从字典中删除项目不能更新新列表;该结构不是字典上的实时视图。

为此,您必须在每次迭代时重新排序字典,并跟踪迭代位置:

def sorted_view(d):
    pos = 0
    while pos < len(d):
        yield sorted(d.items())[pos]
        pos += 1

这是非常低效的;排序是一项相对昂贵的操作。

更有效的方法是按排序顺序存储仅键,然后测试(如果键仍然可用):

def min_key_order(adict:dict):
    for key in sorted(adict):
        if key in adict:
            yield (key, adict[key])

这将不会检测您是否添加了更多键。

【讨论】:

    猜你喜欢
    • 2020-09-13
    • 2013-09-15
    • 1970-01-01
    • 1970-01-01
    • 2022-12-05
    • 2021-09-04
    • 2018-01-05
    • 2011-02-15
    • 2014-09-10
    相关资源
    最近更新 更多