使用列表作为值构建一个 Python 字典 - 为什么看似相同的代码会给出不同的结果?

Constructing a Python dict with lists as values - why does seemingly equivalent code gives different results?

我希望从另一个字典的键构建一个 Python dict 并构建新列表以用作字典值。我写了两段代码,我认为它们是等价的,但实际上不是。

我更喜欢第一段代码,因为它没有在循环中使用新的列表对象,也没有在末尾使用额外的赋值行,如第二段代码所示。我希望使用 dict.fromkeys() 可以消除对这些的需求并使代码 neater/more 可读。

代码 1:

class_list = ['a','b','c','d']
X_classes = {'foo':['a','b'],'bar':['c','d']}
X_indices = dict.fromkeys(X_classes,[]) # i.e., {'foo':[],'bar':[]}
for xc in X_classes.items():
    for c in xc[1]:
        X_indices[xc[0]].append(class_list.index(c))

代码 2:

class_list = ['a','b','c','d']
X_classes = {'foo':['a','b'],'bar':['c','d']}
X_indices = {}
for xc in X_classes.items():
    indices = []
    for c in xc[1]:
        indices.append(class_list.index(c))
    X_indices[xc[0]] = indices

代码 1 产生意外结果:X_indices = {'foo':[0,1,2,3],'bar':[0,1,2,3]}。这促使我编写了代码 2,它产生了预期的结果:X_indices = {'foo':[0,1],'bar':[2,3]}

如果有人能向我解释为什么这两段代码会产生不同的结果,我将不胜感激。

因为dict.fromkeys使用你给它的对象作为值:即每次相同的对象。所以字典中的每个值都是对同一个列表的引用。

fromkeys 仅对不可变值(例如字符串或整数)真正有用。

但是,更简洁的实现方式是使用列表理解。另请注意,您可以在项目的迭代中使用元组解包。

for k, v in X_classes.items():
     X_indices[k] = [class_list.index(c) for c in v]