我想更改列表的值,该列表是字典的值。当我用pythonic方式对它进行编码时它不起作用,但是当我使用列表的经典索引时它确实有效。 为了说清楚我的意思,我写了一个小演示。我想在列表中将所有低于4的值增加一个。
A = [1, 2, 3, 4, 5]
x = {"a": [1, 2, 3, 4, 5]}
print("example 1, this works")
A = [a+1 if a < 4 else a for a in A]
print(A)
print("example 2, this not")
for v in x.values():
v = [a + 1 if a < 4 else a for a in v]
print(x)
print("example 3, this not either")
for v in x.values():
for a in v:
a = a+1 if a < 4 else a
print(x)
print("example 4, but this does")
for v in x.values():
for i in range(len(v)):
if v[i] < 4: v[i] += 1
print(x)
输出:
example 1, this works
[2, 3, 4, 4, 5]
example 2, this not
{'a': [1, 2, 3, 4, 5]}
example 3, this not either
{'a': [1, 2, 3, 4, 5]}
example 4, but this does
{'a': [2, 3, 4, 4, 5]}
有两件事令人费解: 1.根据是否是dict值,对列表进行不同的处理。 2.根据您应用的循环技术,更改列表值是否有效。
有没有超出我的理由? (可能)如果是,那是什么?
答案 0 :(得分:1)
在此代码中:
for v in x.values():
v = [a + 1 if a < 4 else a for a in v]
您正在为v
创建新引用,该引用在下一次迭代时会丢失,因此它不会反映在字典中。我会这样做:
for v in x.values():
v[:] = [a + 1 if a < 4 else a for a in v]
所以引用没有改变,dict也会更新。另一种方法是通过键访问值。您正在创建另一个引用,但它已存储在字典中:
for k in x:
x[k] = [a + 1 if a < 4 else a for a in v]
您的问题的示例(4)适用于相同(反向)原因:您正在处理字典中包含的v
的引用而不修改它,因此更改会反映在字典中
答案 1 :(得分:0)
有趣的问题。我认为这的关键在于dict方法.values()返回view object而不是对该键的值的直接引用。
因此,您无法通过更改.values()返回的列表来更改词典列表值。所以你需要直接访问字典元素。一种方法是使用.items()代替:
x = {"a": [1, 2, 3, 4, 5]}
for key, value in x.items():
x[key] = [a + 1 if a < 4 else a for a in value]
有关更多讨论,另请参阅this question中的评论。