我正在遍历元组列表和字符串列表。字符串是列表中项目的标识符。我有一个字典,其字符串标识符为键,并且每个值都有一个最初为空的列表。我想从元组列表中向每个键添加一些内容。我正在做的简化版本是:
tupleList = [("A","a"),("B","b")]
stringList = ["Alpha", "Beta"]
dictionary = dict.fromkeys(stringList, []) # dictionary = {'Alpha': [], 'Beta': []}
for (uppercase, lowercase), string in zip(tupleList, stringList):
dictionary[string].append(lowercase)
我希望这会给dictionary = {'Alpha': ['a'], 'Beta': ['b']}
,但我发现{'Alpha': ['a', 'b'], 'Beta': ['a', 'b']}
。有谁知道我做错了什么?
答案 0 :(得分:5)
您的问题是您通过引用共享两个键之间的列表。
dict.fromkeys
不会为每个键创建新列表,但会为所有键提供相同列表的引用。其余代码看起来是正确的:)
而不是这样你应该使用defaultdict,基本上它是一个dict,如果它们不存在就会创建新值,如果它们存在则会检索它们(并且不需要if / else插入项目以检查它是否已存在)。它在这种情况下非常有用:
from collections import defaultdict
tupleList = [("A","a"),("B","b")]
stringList = ["Alpha", "Beta"]
dictionary = defaultdict(list) # Changed line
for (uppercase, lowercase), string in zip(tupleList, stringList):
dictionary[string].append(lowercase)
答案 1 :(得分:2)
问题在于,当你调用dict.fromkeys
并将列表作为每个键的默认项传递时,python使用相同的列表,列表不是不可变的,因此对列表的一次更改会影响它在任何引用它的位置,你可以做的就是在没有任何参数的情况下调用dict.fromkeys
,这将默认项设置为None,然后你有一个if语句来检查它是否为None并初始化两个不同的列表。然后,如果它不是None(当它已经存在时),则附加到该列表。
tupleList = [("A","a"),("B","b")]
stringList = ["Alpha", "Beta"]
dictionary = dict.fromkeys(stringList) # dictionary = {'Alpha': [], 'Beta': []}
for (uppercase, lowercase), string in zip(tupleList, stringList):
#print(id(dictionary[string])) uncomment this with your previous code
if dictionary[string] is None:
dictionary[string] = [lowercase]
else:
dictionary[string].append(lowercase)