修改作为dict值的列表

时间:2016-12-17 23:01:26

标签: python list dictionary

我想更改列表的值,该列表是字典的值。当我用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.根据您应用的循环技术,更改列表值是否有效。

有没有超出我的理由? (可能)如果是,那是什么?

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中的评论。