【问题标题】:Why can't I append just one value in a dictionary using python [duplicate]为什么我不能使用 python 在字典中附加一个值 [重复]
【发布时间】:2020-05-19 13:06:47
【问题描述】:

这是我正在从事的项目的一部分,我的问题是我不知道为什么将值分配给所有键,而我只想将它们附加到键为“A”的项目中,是否有另一种思考方式,我需要附加列表,为每个键创建一个大列表。

speakers = ['A','B']
fragments = dict.fromkeys(speakers,[])
TAGS = ['A', ['121560', '124390']]
fragments[TAGS[0]].append(list(map(int,TAGS[1])))
print(fragments)
{'A': [[121560, 124390]], 'B': [[121560, 124390]]}

我需要获得: {'A': [[121560, 124390]], 'B': []}

如果我再做一次: fragments[TAGS[0]].append(list(map(int,TAGS[1])))

那么我应该得到: {'A': [[121560, 124390],[121560, 124390]], 'B': []}

谢谢!

【问题讨论】:

  • 我通过使用:fragments = {i:[] for i in speakers} 解决了这个问题,就像 Alexander 和 Tomeriko 所说,他们共享内存,所以值复制到字典中的所有键。

标签: python list dictionary append


【解决方案1】:

这个问题是可变默认参数问题的变体:"Least Astonishment" and the Mutable Default Argument

问题是AB 的两个列表实际上是同一个!

>>> id(fragments['A']) is id(fragments['B'])
True  # They both point to the same list object in memory.

一种解决方案是使用字典推导来用空列表实例化您的字典。

fragments = {k: list() for k in speakers}

另一种解决方案是使用带有列表的defaultdict 作为默认工厂。

from collections import defaultdict

fragments = defaultdict(list)

【讨论】:

  • 这实际上与可变的默认参数没有任何关系。 语言中没有任何东西阻止dict.fromkeys复制该对象,它根本不会。
  • 另请注意,id(<some expression>) == id(<some expression>) 如果您不理解,可能会给您带来误导性结果,例如,考虑id([]) == id([])。这通常会返回True,尽管这是两个不同的list 正在创建的对象。使用<some expression> is <some expression> 始终是最佳实践
  • @juanpa.arrivillaga 我不同意你的第一点,因为fromkeys 将每个键的值设置为传递给value 的单个参数,在这种情况下是单个列表对象。这种情况类似于可变默认参数情况,它也传递一个可变对象,该对象由对象的实例共享。
  • 但它不涉及默认值。我的意思是,您是对的,这是相同的根本原因,即对象被重用,但对于x = []; y = []; x.append('foo') 也可以这样说。但是,如果您知道并理解默认参数的工作原理,那仍然无法告诉您为什么 dict.fromkeys 会这样工作,因为它不处理默认值。
  • 我没有说问题完全一样,我说这是一个变种。 OP 期望每个键都有单独的列表对象,但由于 fromkeys 构造函数的调用方式而得到了相同的对象。 OP 没有意识到这会导致分配相同的列表对象作为每个键的值。
【解决方案2】:

您的问题的答案正是documentation of fromkeys()

fromkeys() 是一个返回新字典的类方法。 价值 默认为None。所有的值都只引用一个实例, 所以通常 value 是一个可变对象是没有意义的 比如一个空列表。要获得不同的值,请改用dict comprehension

【讨论】:

    猜你喜欢
    • 2016-03-24
    • 2017-10-21
    • 1970-01-01
    • 2011-03-13
    • 2020-04-09
    • 1970-01-01
    • 2021-12-26
    • 2020-10-06
    • 2020-02-28
    相关资源
    最近更新 更多