我发现我经常使用以下逻辑:
- 对一些
值
做一些 Action ; - 从序列中取出下一个
x
; - 以某种方式将
值
修改为x
; - 对结果值执行相同的操作;
- 当序列不为空时转到步骤 2。
例如,value
可以是一个二维点,序列可以包含二维向量。
我为此编写了一个简单的函数,但我对标准库中的类似物很好奇。这对我来说似乎是很常见的场景,但到目前为止我在 itertools
中没有找到任何东西。
def iter_transform(value, sequence, transform):
yield value
for v in sequence:
value = transform(value, v)
yield value
print(list(iter_transform(10, [+3, +4, -7, -5], lambda x, y: x + y)))
输出:
[10, 13, 17, 10, 5]
更新
将值本身添加到列表中并不总是那么简单。当然,当我们谈论数字或坐标时,总有一个零
,转换是算术。
但即使 value
和 x
的类型也可能不同:
print(list(iter_transform('values:', [+3, +4, -7, -5], lambda x, y: x + ' ' + str(y))))
输出:
['values:', 'values: 3', 'values: 3 4', 'values: 3 4 -7', 'values: 3 4 -7 -5']
请您参考如下方法:
结合内置的 reduce()
函数和列表理解的一种解决方案:
In [1]: l = [+3, +4, -7, -5]
In [2]: [reduce(lambda x, y: x + y, l[:i+1]) for i in range(len(l), 10)]
Out[2]: [10, 13, 17, 10, 5]
但这不是很有效,因为 reduce 函数做了太多的重复计算。
更新:另一个使用 reduce() 的解决方案,更有效但不那么直接。
In [1]: l = [+3, +4, -7, -5]
In [2]: result = [l[0]]
In [3]: reduce(lambda x, y: result.append(x + y) or (x + y), l, 10)
Out[3]: 5
In [4]: result
Out[4]: [10, 13, 17, 10, 5]