这类标题有很多问题,但它们并没有真正帮助我。我甚至可能问错了。
我有一个数据结构,看起来像这样:
dd = {1: [(1, 1, 0, 0), (2, 1, 0, 0), (3, 1, 0, 0)],
2: [(1, 2, 0, 0), (2, 2, 0, 0), (3, 2, 0, 0)]}
我试图通过从0开始的增量来修改每个元组中的值索引2,以便返回:
{1: [(1, 1, 0, 0), (2, 1, 30, 0), (3, 1, 60, 0)],
2: [(1, 2, 0, 0), (2, 2, 30, 0), (3, 2, 60, 0)]}
到目前为止,我可以通过这样做打印值,但我不清楚如何实际更改字典。我确实做得很糟糕,效率很低;我不需要任何方法,只要它返回所需的数据结构:
interval = 30
dd = {1: [(1, 1, 0, 0), (2, 1, 0, 0), (3, 1, 0, 0)],
2: [(1, 2, 0, 0), (2, 2, 0, 0), (3, 2, 0, 0)]}
for k, v in dd.items()
dist_from_origin = 0
for row in v:
row = list(row)
row[2] = dist_from_origin
dist_from_origin += interval
row = tuple(row)
Printing显示行更新,但不更新v
和dd
本身的值。我哪里做错了?我怎样才能把它压缩成既有效又不像垃圾的东西呢?
这里有一个列表推导式的选项:
{k:[(a,b,30*i,d) for i, (a,b,c,d) in enumerate(v)] for k,v in dd.items()}
它的作用是将更新后的列表与字典中的每个元素关联。更新后的列表将具有与之前相同的元组,除了在第三个位置有您的值30
乘以列表内元组的索引。
当您将元组转换为列表时,您不会更改v
中的内容,而是在v
之外创建新列表。因此,您需要做的是将v
中的元组替换为新创建的元组。
要修复问题中的代码,您可以尝试这样做:
interval = 30
dd = {1: [(1, 1, 0, 0), (2, 1, 0, 0), (3, 1, 0, 0)],
2: [(1, 2, 0, 0), (2, 2, 0, 0), (3, 2, 0, 0)]}
for k, v in dd.items()
dist_from_origin = 0
for i, row in enumerate(v):
# this is taking row and creating a list
# it does not do anything to the original tuple
row = list(row)
row[2] = dist_from_origin
dist_from_origin += interval
row = tuple(row)
# this is the part where you replace the original tuple
# with the one you just created
v[i] = row
一个更紧凑的方法可以做同样的事情,参见@lemon
的答案。