【问题标题】:Are dict comprehensions evaluated incrementally in Python?dict 理解是否在 Python 中增量评估?
【发布时间】:2021-06-08 23:38:51
【问题描述】:

我假设purgepurge2 的结果在以下代码中是相同的(删除重复元素,保留第一次出现的元素及其顺序):

def purge(a):
    l = []
    return (l := [x for x in a if x not in l])
def purge2(a):
    d = {}
    return list(d := {x: None for x in a if x not in d})
t = [2,5,3,7,2,6,2,5,2,1,7]
print(purge(t), purge2(t))

但它看起来像 dict 推导式,与列表不同,d 的值是增量构建的。这是实际发生的事情吗?我是否从这个示例代码中正确推断出dict 理解的语义以及它们与list 理解的区别?它是否仅适用于理解,或者也适用于引用分配给字典的其他右侧(例如,嵌套在其他表达式中的理解、涉及迭代器的东西、除dict 以外的类型的理解)?它在哪里指定并且可以查阅完整的语义?或者它只是一个未记录的实现行为,不值得依赖?

【问题讨论】:

  • 字典不能有重复的键。它只是忽略了您尝试添加的重复项,if 无效。
  • 你得到与return list({x: None for x in a})相同的结果
  • 哦,既然你提到了,那就太明显了。谢谢!愿意回答,所以我会接受?
  • 我从an answer to another question 那里得到它并简化了。这让我没有注意到进一步简化的可能性。
  • 此外,d 的值在理解过程中不会更新。为了实现增量,通常你想显式地编写一个 for 循环,或者使用一个在其范围内捕获 d 的 lambda。

标签: python dictionary variable-assignment dictionary-comprehension


【解决方案1】:

这里没有什么“增量”。在字典理解完成之前,海象运算符不会分配给变量。 if x not in d 指的是原始的空字典,而不是您使用推导式构建的字典,就像具有列表推导式的版本指的是原始的 l

过滤掉重复项的原因仅仅是因为字典键始终是唯一的。试图创建一个重复的键只会忽略第二个。就像你写的一样:

return {2: None, 2: None}

你只会得到{2: None}

所以你的功能可以简化为

def purge2(a):
    return list({x: None for x in a})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-02
    • 2023-03-23
    • 1970-01-01
    • 2011-05-11
    • 2023-03-08
    • 2016-11-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多