为什么附加到字典中的列表有不同的结果?

ste*_*eve -1 python dictionary list append

Python 3.7.6(默认,2020 年 1 月 8 日,20:23:39)[MSC v.1916 64 位 (AMD64)]

my_list = ["a","b","c"]

dict_one = {key:[] for key in my_list}
print(dict_one)
{'a': [], 'b': [], 'c': []}

dict_two = dict.fromkeys(my_list, [])
print(dict_two)
{'a': [], 'b': [], 'c': []}

dict_one['a'].append('some_data')
dict_two['a'].append('some_data')

print(dict_one)
{'a': ['some_data'], 'b': [], 'c': []}

print(dict_two)
{'a': ['some_data'], 'b': ['some_data'], 'c': ['some_data']}
Run Code Online (Sandbox Code Playgroud)

我对 dict_one 和 dict_two 期望相同的结果。谁能解释一下区别?

che*_*ner 6

它是“Least Astonishment”和“Mutable Default Argument” 的变体。

fromkeys不会为它添加到它正在构建的字典的每个值创建一个新的空列表;它使用您提供的相同(可变)值作为第二个参数。


顺便说一句,如果有一种方法可以提供一个工厂来生产价值,那就太好了;然后你可以写

dict_three = dict.fromkeys(my_list, factory=lambda: [])
Run Code Online (Sandbox Code Playgroud)

类似于如何defaultdict使用函数为新键生成初始值:

d = defaultdict(list)  # *not* d = defaultdict([])
Run Code Online (Sandbox Code Playgroud)