Python 删除范围内的奇数

Python 删除范围内的奇数,python,Python,我试图创建一个代码,删除用户定义范围内的奇数(例如,4到10之间)。到目前为止,我有: def even(x,y): if x > y: return None else: s = list(range(x, y+1)) for i in s: if s[i]%2!=0: del s[i] return s even(4,10) 当我运

我试图创建一个代码,删除用户定义范围内的奇数(例如,4到10之间)。到目前为止,我有:

def even(x,y):
    if x > y:
        return None
    else:
        s = list(range(x, y+1))
        for i in s:
            if s[i]%2!=0:
                del s[i]
                return s

even(4,10)

当我运行代码时,它返回[4,5,6,7,8,10],而不是[4,6,8,10]。知道为什么吗?

这是正确的代码。在python中,您可以按项从列表中删除,按索引删除:

def even(x,y):
 if x > y:
    return None
 else:   
    s = list(range(x, y+1))
    for i in s:
        if i%2 != 0:
            s.remove(i)
    return s
even(4,10)

创建一个更大的集合,然后删除您不想要的项目,这没有什么意义

我想,如果你只是在列表中预先列出你想要的东西会更好:

def even(lo, hi):
    if lo > hi: return None # although [] may make more sense
    return [item for item in range(lo, hi + 1) if item % 2 == 0]
我之所以声明,对于
lo>hi
的情况,最好返回
[]
,是因为对于其他边缘情况,例如
偶数(3,3)
,会返回

根据以下文字记录,这是您想要的:

>>> def even(lo, hi):
...     if lo > hi: return None
...     return [item for item in range(lo, hi + 1) if item % 2 == 0]
...
>>> even(4, 10)
[4, 6, 8, 10]

你的代码有三个地方出错

  • 使用
    s[i]
    访问列表中的
    i
    th项,但
    i
    已保留列表项,因为您在s中为i执行了

    >>> s = list(range(4, 11))
    >>> s
    [4, 5, 6, 7, 8, 9, 10]
    >>> for i in s:
    ...   print(i)
    ... 
    4
    5
    6
    7
    8
    9
    10
    
    您的循环实际检查的
    s[i]
    是:

    >>> for i in s:
    ...   print(s[i])
    ... 
    8    # i=4, s[4]
    9    # i=5, s[5]
    10   # i=6, s[6]
    
  • 当您找到一个奇数(
    s[5]=9
    9%2!=0
    )时,您会立即中断循环,因为
    返回s
    。因此,循环只会删除它找到的第一个奇数,然后立即中断循环

    >>> s = list(range(4, 11))
    >>> for idx, i in enumerate(s):
    ...   print(i)
    ...   if i%2 != 0:
    ...     print("removing i")
    ...     del s[idx]
    ... 
    4
    5
    removing i
    7  # notice that 6 was now skipped after removing 5
    removing i
    9  # notice that 8 was now skipped after removing 7
    removing i
    
    也许它只是错误地缩进了,但是
    返回s
    应该在函数的末尾,而不是在循环中

  • >>> s = list(range(4, 11))
    >>> for idx, i in enumerate(s):
    ...   print(i)
    ...   if i%2 != 0:
    ...     print("removing i")
    ...     del s[idx]
    ... 
    4
    5
    removing i
    7  # notice that 6 was now skipped after removing 5
    removing i
    9  # notice that 8 was now skipped after removing 7
    removing i
    
  • 在列表上进行迭代时,您正在从列表中删除项目。这绝不是一个好主意,因为那样会打乱循环

    >>> s = list(range(4, 11))
    >>> for idx, i in enumerate(s):
    ...   print(i)
    ...   if i%2 != 0:
    ...     print("removing i")
    ...     del s[idx]
    ... 
    4
    5
    removing i
    7  # notice that 6 was now skipped after removing 5
    removing i
    9  # notice that 8 was now skipped after removing 7
    removing i
    
  • 话虽如此,正确的方法是迭代输入列表,但结果/输出应该位于不同的列表上。这样,循环就不会出错。最简单(也是最“pythonic”)的方法是使用:

    或者,您可以在
    期间使用
    手动循环,然后跟踪正确的列表索引:

    def even(x,y):
        if x > y:
            return None
        else:
            s = list(range(x, y+1))
            idx = 0
            while idx < len(s):
                if s[idx]%2!=0:
                    del s[idx]
                    # after this, s[idx] now points to the next item
                else:
                    idx += 1
                    # move to the next item
    
        return s
    
    def偶数(x,y):
    如果x>y:
    一无所获
    其他:
    s=列表(范围(x,y+1))
    idx=0
    当idx
    如果i%2==0,则使用
    [i表示范围(x,y+1)内的i]