初始化一个空列表的字典

时间:2020-04-30 14:36:13

标签: python list dictionary

我试图初始化一个空列表的字典以便附加到它们,但是这导致了一些奇怪的行为:

def solution(A):
    d = dict.fromkeys(set(A), [])
    for i in range(len(A)):
        d[A[i]].append(i)
    print(d)

输入:

[3, 4, 3, 2, 3, -1, 3, 3]

输出:

{2: [0, 1, 2, 3, 4, 5, 6, 7],
 3: [0, 1, 2, 3, 4, 5, 6, 7],
 4: [0, 1, 2, 3, 4, 5, 6, 7],
-1: [0, 1, 2, 3, 4, 5, 6, 7]}

dict.fromkeys似乎将所有列表初始化为指向内部相同列表的指针,这是怎么回事?我怎么知道这是行为/为什么会是行为?有没有办法告诉口译员不要这样做?

3 个答案:

答案 0 :(得分:1)

所有列表都是同一个对象。 []只是一个文字表达式,在传递给dict.fromkeys之前会先求值。函数如何知道如何复制任何随机对象?

如果您想要这种行为,请选择一个collections.defaultdict

from collections import defaultdict

def solution(A):
    d = defaultdict(list)  # `list` is a factory funtion that can be called repeatedly
    for i in range(len(A)):
        d[A[i]].append(i)
    print(d)
    # or, if you dislike the output (note, it is a dict already)
    # print(dict(d))

答案 1 :(得分:1)

我怎么知道这是行为

Python documentation says it并警告您:

来自键的类方法(可迭代 [,])

使用 iterable 中的键并将值设置为 value 。创建新词典。

fromkeys()是返回新字典的类方法。 value 默认为None。所有的值仅涉及一个实例, 因此通常将 value 当作可变对象是没有意义的 例如空列表。要获取不同的值,请使用dict 而是理解。

答案 2 :(得分:0)

在fromkeys中,如果提供的值是可变的(如列表),则每个键的值都将引用同一对象,因此所有值都将立即更新。您可以通过将其附加到原始列表中来进行测试,以产生与得到的结果相同的结果:

def solution(A):
    lst = []
    d = dict.fromkeys(set(A), lst)
    for i in range(len(A)):
        lst.append(i)
    print(d)

除了提供其他答案外,您还可以使用字典理解路线:

def solution(A):
    d = { key : [] for key in A }
    for i in range(len(A)):
        d[A[i]].append(i)
    print(d)