如何对依赖于以前元素的列表元素执行操作?

时间:2014-05-27 01:10:34

标签: python list

使用map可以对列表中的当前元素进行操作:

l = [1,2,3,4,5,6];


print(list(map(lambda x: x*2, l)))  
# gives [2, 4, 6, 8, 10, 12]

在上面,对l中的所有元素进行乘以2。但是,如果l中的前一个值是奇数,那么如何通过l中的2个元素多次使用?可以使用地图吗?

例如获取:

[1,4,3,8,5,12] % only 2, 4 and 6 from l are multiplyied by 2, because before them there are odd numbers 1,3,5. 

5 个答案:

答案 0 :(得分:3)

如果您在map d版本上执行此操作,则可以使用enumerate

print(list(map(lambda index,x: x*2 if index > 1 and l[index-1] & 1 else x, enumerate(l))))

然而,正如您可能已经注意到的那样,这真的不太可读。最好只使用列表推导或for循环:

print([x*2 if index > 1 and l[index-1] & 1 else x
       for index, x in enumerate(l)])

答案 1 :(得分:2)

您可以将zipmap结合使用:

print(l[:1] + list(map(lambda x: x[1]*2 if x[0] & 1 else x[1], zip(l, l[1:]))))

请注意,我必须显式地添加列表的第一个元素,因为它没有要测试的先前元素。

答案 2 :(得分:2)

您可以zip列表以及列表的切片副本以配对所有项目:

>>> l = [1, 2, 3, 4, 5, 6]
>>> zip(l, l[1:])
[(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]

答案 3 :(得分:0)

您可以使用可调用的内容来跟踪您之前的值。取决于你想要的摘要:

prev = [0]
def callback(x):
    val = ((prev[0] % 2) + 1) * x
    prev[0] = x
    return val

print list(map(callback, l))

答案 4 :(得分:0)

我意识到这可能只是一个微不足道的例子,但是值得一提的是,在你的示例中,条件“如果前一个值是奇数”相同当前值甚至是“(至少对于您的样本输入)。在这种情况下,我只会使用

print([x if x&1 else x*2 for x in l])

对于更一般的情况,并假设条件可能比“前一项是奇数”更复杂,我会采取几行来清楚地表达解决方案。 Python的generators非常合适:

>>> def double_if_prev_odd(l):
...     prev_odd = False # initial condition for 1st element
...     for x in l:
...             yield x**2 if prev_odd else x
...             prev_odd = x&1
...
>>> list(double_if_prev_odd(l))
[1, 4, 3, 16, 5, 36]