在枚举中访问元组?

Accessing a tuple in enumerate?

我想遍历一个列表并对所有元素求和。除了,如果数字是 5,我想跳过 5 之后的数字。例如:

x=[1,2,3,4,5,6,7,5,4,3] #should results in 30

我只是不确定在使用枚举时如何访问元组的索引。我想做的是使用 if 语句,如果前一个索引处的数字 == 5,则继续循环。

谢谢

sumenumerate

结合使用

例如:

x=[1,2,3,4,5,6,7,5,4,3]
print(sum(v for i, v in enumerate(x) if (i == 0) or (x[i-1] != 5)))

输出:

30

简单、详细的方式:

SKIP_PREV = 5
x = [1,2,3,4,5,6,7,5,4,3]
prev = -1
s = 0
for num in x:
    if prev != SKIP_PREV:
        s += num
    prev = num
print(s)
# 30

紧凑,可能不太清楚的方式:

SKIP_PREV = 5
x = [1,2,3,4,5,6,7,5,4,3]
s = sum(num for i, num in enumerate(x) if i == 0 or x[i - 1] != SKIP_PREV)
print(s)
# 30

itertools documentation has a recipe for this called pairwise. You can either copy-paste the function or import it from more_itertools(需要安装)

演示:

>>> from more_itertools import pairwise
>>> 
>>> x = [1,2,3,4,5,6,7,5,4,3]
>>> x[0] + sum(m for n, m in pairwise(x) if n != 5)
30

编辑:

But what if my datastructure is iterable, but does not support indexing?

在这种情况下,上述解决方案需要稍作修改。

>>> from itertools import tee
>>> from more_itertools import pairwise
>>> 
>>> x = (n for n in [1,2,3,4,5,6,7,5,4,3]) # generator, no indices!
>>> it1, it2 = tee(x)
>>> next(it1, 0) + sum(m for n, m in pairwise(it2) if n != 5)
30

您可以将列表与其自身的移位版本配对。这应该有效:

sum(val for (prev, val)
    in zip(itertools.chain((None,), x), x)
    if prev != 5 )

不喜欢被点赞的漏洞百出的单行代码。

所以这是带有 for 循环的答案。

x=[1,2,3,4,5,6,7,5,4,3, 5] #should results in 35. 

s = 0
for i, v in enumerate(x):
    if i != 0 and x[i-1] == 5: 
        continue 
    s += v

print(s)

如果您乐于使用第 3 方库,可以使用带整数索引的 NumPy:

import numpy as np

x = np.array([1,2,3,4,5,6,7,5,4,3])

res = x.sum() - x[np.where(x == 5)[0]+1].sum()  # 30

另见 What are the advantages of NumPy over regular Python lists?

迄今为止最长的代码。反正不用枚举,就是一个简单的FSM.

x = [1,2,3,4,5,6,7,5,4,3]
skip = False
s = 0 
for v in x:
    if skip:
        skip = False
    else:
        s += v
        skip = v == 5
print(s)