在 Python 中,循环不 "save" 列表中具有相同值的项目

In Python, loop for don't "save" items with same value in a list

祝你好运。

我想对一个列表的索引求和,我这样做对每个列表都正常工作,但是如果传递的列表(如参数)有重复的项目,代码就不会像它应该的那样工作。

例如,我有这个代码:

def sumar_indices_pares(array):
    """
        sums even-indexes elements 
    """
    suma = []
    while array == []:
        return 0
    for i in array:
        if array.index(i) % 2 == 0 :
            suma.append(i)
    return sum(suma)

如果我通过下一个类似的论点:

   sumar_indices_pares([1,2,3,4,5])    # give 9 and this is ok

但是,当我将 like 参数放入一个包含重复项的列表时,循环 'for' 迭代并且当它的索引 [1] 像不偶数时(西班牙语中的 "Par" )显然不会t 对该索引求和,但是当循环到达偶数索引但具有与先前索引相同的值时,代码不会对偶数索引求和,例如:

sumar_indices_pares([1,2,3,4,2])   # it gives 4 and should be 6 because (1+3+2) = 6 

因此,值为 2 的第一个索引不是偶数,因此不要对该索引求和,而应该对值为 2 的下一个索引求和,因为它是偶数索引。

注意:参数列表为空将 return 0,那部分没问题 ;)。

有什么解决办法吗?谢谢。

你应该使用enumerate。以您尝试的方式查找索引效率低下,并且如您所见,当出现重复项时会给出错误的答案。

def sumar_indices_pares(array):
    """
        sums even-indexes elements 
    """
    suma = []
    if array == []:
        return 0
    for i, item in enumerate(array):
        if i % 2 == 0 :
            suma.append(item)
    return sum(suma)

如果将 sum 与生成器表达式一起使用,则不需要空列表的特殊情况

def sumar_indices_pares(array):
    """
        sums even-indexes elements 
    """
    return sum(item for i, item in enumerate(array) if i % 2 == 0)

index() 将 return 给定值的 第一个 索引。如果你有重复的值,它确实总是 return 第一个值的索引。

例如,给定列表 [1,3,3,4,6,3]

index:    0   1   2   3   4   5
values:   1   3   3   4   6   3

每次调用 index() 都会从 "left to right" 开始新的搜索,当找到第一个搜索值时停止。例如,如果你正在寻找 3 它会做这样的事情:

index:    0   1   2   3   4   5
values:   1   3   3   4   6   3

index(3)  No  Yes
              ^
              |
            3 is found
            stop here

请注意,即使它在您有非重复值时有效,它也不是很有效,因为程序必须在每次迭代时在列表中执行线性搜索。


对于小型列表,迭代 even 项的规范方法可能是使用切片语法:

suma = array[::2]
return sum(suma)

为了完整起见,如果你需要遍历奇数索引,你会写:

return sum(array[1::2])

对于长列表,这也可能效率低下,因为这会使列表的 副本 仅包含必需的项目。如果您需要处理此类列表,您可能需要查看 itertools.islice:

>>> l=[0,1,2,3,4,5]

>>> import itertools
>>> itertools.islice(l, 0, None, 2)   # Returns an iterator from first (idx 0)
                                      # to last (None) item, stepping by 2
                                      # -- not a (partial) copy of the list
<itertools.islice object at 0x7f5369ccf680>
>>> sum(itertools.islice(l, 0, None, 2))
6

您实际上可以在一行中执行此操作,使用@SylvainLeroux 提到的切片:

sum(array[::2])