【问题标题】:Next() skips the actual and next item in list, when it should only skip the actual itemNext() 跳过列表中的实际和下一个项目,而它应该只跳过实际项目
【发布时间】:2019-11-25 11:38:33
【问题描述】:

我正在编写一个程序,它给出一个整数列表,识别最小值,然后用列表的次要索引删除最小值。

例如:list = [3, 6, 15, 2, 4, 2] 应该返回 [3, 6, 15, 4, 2] 请注意,由于列表中的次要索引,前 2 个被删除。

这是我的全部代码:

def remove_smallest(numbers):
    mylist = []
    if not numbers:
        return mylist 
    minimo = min(numbers)
    if numbers.count(minimo) > 1:
        numbers = numbers[::-1] #My solution to the minor index is to reverse the list and loop. Then reverse again.

        #mylist = [item for item in numbers if item != minimo and item not in mylist]  #I tried to use a list comprehension, with awful results.

        it = iter(numbers)
        for item in it:
            if item == minimo and item in mylist:
                next(it, None)
                continue
            mylist.append(item)

    print(mylist[::-1])

remove_smallest([2, 4, 5, 1, 2, 1])

前两项将附加到“mylist”(1, 2)。 然后,因为 1 在 mylist 上,它会跳过它然后继续。到目前为止一切都很好,但是当它应该选择 5 时,它没有,而是直接进入 4 然后 2,导致在程序末尾看起来像这样的数组: [2, 4, 2, 1 ] 什么时候应该返回 [2, 4, 5, 2, 1]

谢谢

【问题讨论】:

  • 删除next(it, None),它会给出正确的结果。
  • 为了澄清 为什么 那就是 - for item in it: 直接推进迭代器,您不需要使用 next() 手动进行。不相关的建议:numbers.remove(min(numbers)) 是解决此用例的单线器
  • for 循环本身(隐式)调用next。你不需要自己做。
  • 谢谢,它也成功了!

标签: python python-3.x list loops iterator


【解决方案1】:

删除下一条语句使代码按预期方式工作。 for 循环已经在迭代器上调用 next,因此无需手动。

def remove_smallest(numbers):
    mylist = []
    if not numbers:
        return mylist 
    minimo = min(numbers)
    if numbers.count(minimo) > 1:
        numbers = numbers[::-1] #My solution to the minor index is to reverse the list and loop. Then reverse again.

        it = iter(numbers)
        for item in it:
            if item == minimo and item in mylist:
                continue
            mylist.append(item)

    print(mylist[::-1])

remove_smallest([2, 4, 5, 1, 2, 1])

结果:

[2, 4, 5, 2, 1]

【讨论】:

  • 只是建议在 python 中使用 if not numbers 是一种不好的做法 - stackoverflow.com/a/100903/7841468
  • @mishsx 因为一切都假设numbers 是一个列表,然后if not numbers 作为“如果它是空的”检查似乎很好......
【解决方案2】:

我会设计一种新方法,因为我发现你的代码太多了:

def remove_smallest(lst):
    mini = min(lst)
    indx = next((i for i, x in enumerate(lst) if x == mini), -1)
    del lst[indx]
    return lst

这会安全地删除列表中最小元素的第一次出现。

用法

>>> remove_smallest([2, 4, 5, 1, 2, 1])
[2, 4, 5, 2, 1]

【讨论】:

  • 好的,但这将计算min(lst) N 次,其中 N 是列表长度。为什么不只是indx = lst.index(min(lst))
  • @zvone,哎呀!我的错。忽略了这一点。更正了min(lst) 的计算,这可能有助于人们理解next 的工作原理。
【解决方案3】:

一个简单的语句将删除最小值。 l.index(min(l)) 查找最小值的索引。

>>> l = [2,4,5,1,2,1]
>>> del l[l.index(min(l))]
>>> l
[2, 4, 5, 2, 1]

【讨论】:

  • 你不仅解决了我的问题,而且解决了整个练习的目的。
【解决方案4】:

此函数将删除列表中第一次出现的最小数字并返回该数字,列表已就地修改,因此无需返回它:

def pop_smallest(lst):
    smallest = lst.index(min(lst))
    return lst.pop(smallest)

l = [2, 4, 5, 1, 2, 1]
pop_smallest(l)
>>> 1

l
>>> [2, 4, 5, 2, 1]

但如果你不想修改原始列表,那么你需要复制列表并返回新列表

def pop_smallest(lst):
    new_lst = lst.copy()
    smallest = new_lst.index(min(lst))
    new_lst.pop(smallest)
    return new_lst

l = [2, 4, 5, 1, 2, 1]
new_l = pop_smallest(l)

l
>>> [2, 4, 5, 1, 2, 1]
new_l
>>> [2, 4, 5, 2, 1]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多