索引1 /第二个列表项被跳过,没有明显的原因

时间:2016-08-26 14:27:38

标签: python list

我有一个函数,它接受一个列表并删除(一个实例)最小和最大元素,然后取剩余元素的平均值。 运行它不会带来任何错误,虽然在检查结果时我发现它们是不正确的。 这是该计划:

def centered_average(x):
    x.sort()
    y = 0
    for i in x:
        if x.index(i) == 0 or x.index(i) == (len(x)-1):
            print(i, "is being removed")
            x.remove(i)
            i +=1
        else:
            y += i
            print(i, "is being added")
    return (y / len(x))

def average(x):
    return sum(x)/len(x)

(打印功能进行检查)

点击

列表
x = [1,2,3,4,5]

结果是:

1 is being removed
3 is being added
4 is being added
5 is being removed
2.3333333333333335

因此,我们可以假设函数中没有使用x [1],我想知道原因。

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

在删除已在Python中迭代的列表元素时,需要特别注意,就像在函数中一样。 Python正在查看列表的索引并使用它们,但是当您删除第一个元素并且列表已更新到位时,前一个第二个元素(x[1])现在是第一个(x[0])因此将被跳过。

有一种更简单的方法可以做到这一点,不需要这样的循环和额外的条件,如果你想做的就是取不是第一个或最后一个元素的平均值: / p>

def centered_average(x):
    x.sort()
    if len(x) <= 2:
        print "Cannot run with 2 or fewer elements..."
        return 0
    else:
        return sum(x[1:-1])/(len(x)-2.00)

还有其他方法可以做到这一点,但是这个方法应该足够快,并且只要 x 是一个列表就允许你提供的任何情况。希望这会有所帮助。

答案 1 :(得分:1)

问题来自for i in x:。删除第一个元素时,第二个元素(2)成为列表的第一个元素。这意味着在下一次迭代中,您将查找第二个元素,并找到3,因为列表现在是[2,3,4,5]。

相反,您可以先使用x=x[1:-1]删除第一个和最后一个元素。如果您以前从未见过[i:-j]语法,则告诉Python返回从索引i开始的列表,并从结尾返回j个索引。换句话说,这将在您的示例中生成[2,3,4]。之后,您可以返回sum(x)/len(x)

请注意,此代码或原始方法都不适用于少于3个元素的列表。在任一解决方案中除以len(x)时,最终将除以0。