为了账号安全,请及时绑定邮箱和手机立即绑定

初始化空列表的字典

初始化空列表的字典

富国沪深 2022-11-01 15:58:36

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


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 回答

?
肥皂起泡泡

TA贡献1565条经验 获得超1个赞

我怎么知道这是行为

Python 文档说明了这一点并警告您:

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

创建一个新字典,其中键来自可迭代,值设置为value

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


查看完整回答
反对 回复 2022-11-01
?
繁花不似锦

TA贡献1595条经验 获得超4个赞

你所有的列表都是同一个对象。[]只是一个文字表达式,在传递给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))


查看完整回答
反对 回复 2022-11-01
?
子衿沉夜

TA贡献1586条经验 获得超3个赞

在 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)


查看完整回答
反对 回复 2022-11-01

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信