以下是场景:给定 n 列表(长度相同)和整数(实际上长度相同)累加器,就地积累元素和。就地约束在这里是因为我在列表的字典中累积值(哼......很不清楚,请看下面的例子)
编辑:我正在寻找一个不涉及numpy的解决方案
# My lists are long (they are actually pixels in 1000x1000 images)
# but I keep l low for the sake of the example
l = 5
# Values here are arbitrary and won't be repeated in the real word
# e.g. list 1 might be [41,15,0,2,3], etc.
lists = [
{'id': 1, 'values': [12]*l},
{'id': 2, 'values': [42]*l},
{'id': 2, 'values': [25]*l},
{'id': 1, 'values': [6]*l},
]
maps = {
1: [0]*l,
2: [0]*l
}
for item in lists:
# Get the "target" for this list
target = maps[item['id']]
# Element-wise addition of item['values'] to target here!
# This won't work
target = map(lambda x,y:x+y, target, item['values'])
# This neither
target = [(x+y) for x,y in itertools.izip(target,item['values'])]
# For either of the previous to work, I need to re-assign
# the result to 'target', like so
maps[item['id']] = target
虽然它有效但我可以专业地使用它,但我个人不能。
今晚有人能让我睡得更好吗?
答案 0 :(得分:2)
看看numpy。您的代码可以写成:
import numpy as np
l = 5
lists = [
{'id': 1, 'values': np.array([12]*l)},
{'id': 2, 'values': np.array([42]*l)},
{'id': 2, 'values': np.array([25]*l)},
{'id': 1, 'values': np.array([6]*l)},
]
maps = {
1: np.zeros(l),
2: np.zeros(l)
}
for item in lists:
maps[item['id']] += item['values']
您也可以将其调整为2D(图像),无需进一步循环。
答案 1 :(得分:1)
看起来您正在尝试使用字典列表作为表,您应该考虑使用专业数据类型(已针对此进行了优化)。我的建议是panda's dataframe。
答案 2 :(得分:1)
虽然我没有花时间真正弄清楚你的代码,但在我看来,这样的东西可以起作用:
target[:] = [(x+y) for x,y in itertools.izip(target,item['values'])]
唯一的区别是target[:]
而不是target
。分配给列表的切片时,可以进行该分配。考虑:
a = [1,2,3,4]
a[1:3] = ["foo","bar"]
print(a) # [1, 'foo', 'bar', 4]
这会创建一个临时列表(至少在CPython中 - 也许类似于使用JIT编译的pypy可以优化它...)。为避免这种情况,您可以使用生成器(尽管您的代码执行速度可能会受到影响):
a[1:3] = (x for x in iterable)
所以你的最终解决方案可能是(未经测试的):
target[:] = ((x+y) for x,y in itertools.izip(target,item['values']))
答案 3 :(得分:1)
如果您在添加target
时真的试图避免临时性,为什么不做以下事情:
for (i, v) in enumerate(item['values']):
target[i] += v
在你的循环中?当您修改target
时,无需将其重新分配给maps[item["id"]]
...
答案 4 :(得分:0)
这种混淆是否源于重新分配变量target
。请考虑以下事项:
x = [3]
target = x[0] # target = 3
target = 4
print x # prints [3] # x has not been changed
您可以在一行中进行此就地更改,而不是分配给虚拟变量target
。类似于:
maps[item['id']] = map(lambda x,y:x+y, maps[item['id']], item['values'])