我正在尝试读取具有非常相似数据的多个文件。该数据的每一行都有一个accessor_key和一个与之相关的值。我正在尝试创建一个字典,其中accessor_key作为字典键和字典值 - 到目前为止读取的所有值的列表。
我的代码如下所示:
with open(ind_file, "r") as r:
for line in r:
nline = line.strip()
spl = nline.split(",")
if agg_d.has_key(spl[0]):
key = spl[0]
val = spl[1]
dummy = agg_d[key]
dummy.append(val)
agg_d[key] = dummy
print key, agg_d[key]
else:
print "Something is wrong"
print agg_d
print spl[0]
print spl[1]
正如你所看到的,我希望每次都能使值变大,(每次迭代时列表的大小增加1)并将其存储回字典中。 但是,当我运行此程序时,字典中的所有键都采用列表的值。
因此,例如在程序的开头,字典是:
agg_d = {'some_key': [], 'another_key': []}
运行后,它变为:
agg_d = {'some_key': ['1'], 'another_key': ['1']}
应该只是:
agg_d = {'some_key': ['1'], 'another_key': []}
编辑:我找到了我正在寻找的工作。我只是做了:
with open(ind_file, "r") as r:
for line in r:
nline = line.strip()
spl = nline.split(",")
if agg_d.has_key(spl[0]):
key = spl[0]
val = spl[1]
dummy = agg_d[key]
ad = dummy[:]
ad.append(val)
agg_d[key] = ad
print key, agg_d[key]
else:
print "Something is wrong"
print agg_d
print spl[0]
print spl[1]
但我仍然想知道为什么会发生这种情况。 'dummy'是否引用了字典的所有值?我用Python 2.7运行它。
答案 0 :(得分:2)
虚拟'引用字典的所有值?我用Python 2.7运行它。
是。您已添加对列表的引用,并且可能存在对您所观察到的同一列表的多个引用。为了简单说明这一点,试试这个:
dummy = [1,2,3] # creates a list object and assigns reference to the name 'dummy'
d = dict()
d['some key'] = dummy # creates the key 'some key' in the dictionary and assigns its value as the reference to the name 'dummy'
dummy.append(4) # mutates the list referred to by name 'dummy'
# at this point, all references to that object have mutated similarly
print d['some key']
您将观察到以下输出:
>>> [1,2,3,4]
您的解决方法没问题,但您可以改进:
with open(ind_file, "r") as r:
for line in r:
spl = line.strip().split(",")
key, val = spl[0], spl[1]
if key in agg_d:
agg_d[key] = agg_d[key][:].append(val)
print key, agg_d[key]
else:
print "Something is wrong"
print agg_d
print spl[0]
print spl[1]
agg_d[key] = agg_d[key][:].append(val)
这不会改变你的dummy
列表,并将值重新分配给字典。同时避免使用一些不必要的变量,例如nline
和ad
以及dummy
。
答案 1 :(得分:1)
看起来agg_d
已经使用您预期的密钥初始化了。你没有说明这是如何完成的,但我猜测所有的初始值实际上都是相同的列表 - 你在上面的代码中追加了值。
如果您使用每个键的新列表初始化agg_d
,则问题应该消失。你可以用词典理解来做到这一点:
>>> keys = ["a", "b", "c"]
>>> agg_d = {k:[] for k in keys}
>>> agg_d["a"].append(1)
>>> agg_d
{'a': [1], 'c': [], 'b': []}
或者,根据您的需要,您可以在阅读文件时遇到每个密钥时按需初始化每个条目。
您的解决方法有效,因为它用新列表替换原始列表并删除共享引用。
答案 2 :(得分:0)
问题在于,默认情况下,Python只是将列表的引用添加为dict值,而不是列表本身。所以dict值实际上是指向同一个对象的一堆指针。您需要使用您在comment中建议的dummy [:]或copy.deepcopy()更明确地复制列表。