初始化空列表的字典

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


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似乎将所有列表初始化为指向同一列表的指针,这是发生了什么吗?我怎么知道这将是行为/为什么会是行为?有没有办法告诉口译员不要这样做?


富国沪深
浏览 90回答 3
3回答

肥皂起泡泡

我怎么知道这是行为Python 文档说明了这一点并警告您:来自keys的类方法(可迭代[,值])创建一个新字典,其中键来自可迭代,值设置为value。fromkeys()是一个返回新字典的类方法。值默认为None. 所有的值都只引用一个实例,因此value是一个可变对象(例如空列表)通常是没有意义的。要获得不同的值,请改用 dict 理解。

繁花不似锦

你所有的列表都是同一个对象。[]只是一个文字表达式,在传递给dict.fromkeys. 该函数如何知道如何复制任何随机对象?如果您想要这种行为,请选择collections.defaultdict:from collections import defaultdictdef 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))

子衿沉夜

在 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)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python