1

这是场景:给定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

虽然它有效并且我可以专业地接受它,但我个人不能。

谁能让我今晚睡得更好?

4

5 回答 5

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(图像),而无需进一步循环。

于 2012-08-31T12:57:07.270 回答
1

看起来您正在尝试将字典列表用作表格,您应该考虑使用专业数据类型(已为此进行了优化)。我的建议是熊猫的数据框

于 2012-08-31T12:59:11.010 回答
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']))
于 2012-08-31T13:23:57.590 回答
1

如果您在添加时确实尝试避免使用临时对象target,为什么不直接执行以下操作:

for (i, v) in enumerate(item['values']):
    target[i] += v

在你的循环中?并且当您target就地修改时,无需将其重新分配给maps[item["id"]]...

于 2012-08-31T14:09:37.347 回答
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'])
于 2012-08-31T13:06:55.730 回答