简体   繁体   English

ValueError:list.remove(x):x不在列表python中

[英]ValueError: list.remove(x): x not in list python

I'm trying to sort a list from smallest to biggest integers. 我正在尝试从最小到最大整数对列表进行排序。 Unfortunately I get the error stated above when I try to run it. 不幸的是,当我尝试运行它时,出现了上面提到的错误。

Traceback (most recent call last):
  File "lesson_4/selection_sort.py", line 24, in <module>
    print selection_sort([-8, 8, 4, -4, -2, 2]) # [-8, -4, -2, 2, 4, 8]
  File "lesson_4/selection_sort.py", line 14, in selection_sort
    lst.remove(min)
ValueError: list.remove(x): x not in list

Here is the code of selection_sort.py 这是selection_sort.py的代码

def selection_sort(lst):
  sorted = []
  list_len = len(lst) # Store this now because our loop will make it
                    # smaller
  min   = lst[0]
  i     = 1

  while list_len > 0:
    while i < list_len:
      item = lst[i]
      if item < min:
        min = item
      i += 1
    lst.remove(min)
    sorted.append(min)

  return sorted


# Test Code
print "Testing"


print selection_sort([-8, 8, 4, -4, -2, 2]) # [-8, -4, -2, 2, 4, 8]

Thank for helping me out! 感谢您的帮助!

On your first pass through the list, you find the minimum element. 在第一次遍历列表时,您会找到最小元素。 However, on your second pass, min is still set to the minimum element in the original list. 但是,在第二遍时, min仍设置为原始列表中的最小值。 As a result, item < min is never true, and min forever remains the minimum element of the original list. 结果, item < min永远不会为真,并且min永远保持原始列表的最小元素。 Then when you try to remove it, you can't, because you already got rid of that item on the previous pass (unless there is a tie for the minimum, in which case this will happen as soon as all those elements are removed). 然后,当您尝试将其删除时,您将无法执行此操作,因为您已在上一遍中删除了该项目(除非最低要求平分平手,在这种情况下,所有这些元素都将被删除后立即发生) 。

To solve this, just move min = lst[0] inside the first loop, so you reset it to a valid value each time. 要解决此问题,只需在第一个循环内移动min = lst[0] ,以便每次将其重置为有效值。


You've also got some other issues, which I will mention here briefly: 您还遇到了其他一些问题,在这里我将简要提及:

You never update list_len , so you'll get an error at the end of the second pass through the outer loop (when you will attempt to go beyond the length of the list). 您永远不会更新list_len ,因此在通过外循环的第二次传递结束时(当您尝试超出列表的长度时)会出现错误。 You'd also loop forever if it didn't break bist. 如果不破坏双拳,您还将永远循环。 Luckily this whole variable is unneeded: you can use len(lst) in the outer loop, and replace your inner while loop with this: 幸运的是,不需要整个变量:您可以在外部循环中使用len(lst) ,并使用以下内容替换内部while循环:

for item in lst:  # But see below regarding variable names!
    if item < min:
        min = item

This eliminates the need to track i separately and avoids any issues with the length of the list. 这消除了单独跟踪i的需要,并避免了列表长度的任何问题。


Next: this looks like homework, so it's probably not critical at this moment, but it's definitely worth mentioning: if I pass a list to a function called selection_sort , I would be very surprised to discover that after being sorted, my original list is now empty!! 下一步:这看起来像是作业,所以现在可能并不重要,但是绝对值得一提:如果我将一个列表传递给一个名为selection_sort的函数,我会很惊讶地发现排序后的原始列表现在空! It's generally bad form to modify an input unless you're doing so explicitly (eg an in-place sort), so I highly recommend that you do all your work on a copy of the input, to avoid deleting all the content of the original: 除非您明确地进行修改(例如,就地排序),否则通常是修改输入的形式,因此,我强烈建议您对输入的副本进行所有工作,以避免删除原始内容的所有内容:

lst_copy = lst[:]  # If `lst` contains mutable objects (e.g. other lists), use deepcopy instead!
# Do stuff with lst_copy and avoid modifying lst

Finally, you've got two variables shadowing built-in functions: sorted and min . 最后,您有两个变量隐藏了内置函数: sortedmin While this will technically work, it's poor form, and it's best to get into the habit of not naming local variables the same as builtins. 尽管从技术上讲这是可行的,但是它的形式很差,最好养成不要将局部变量命名为与内置变量相同的习惯。 By convention, if it's really the best name for the object, you can just add an underscore to the name to distinguish it from the builtin: min_ and sorted_ (or maybe better, output ), for example. 按照惯例,如果它确实是对象的最佳名称,则可以在名称中添加下划线以将其与内置对象区分开: min_sorted_sorted_ (或者可能更好,为output )。

If you simply want to sort the list, you can use inbuilt sort() function: 如果只想对列表进行排序,则可以使用内置的sort()函数:

>>> lst=[-8, 8, 4, -4, -2, 2]
>>> lst.sort()
>>> lst
[-8, -4, -2, 2, 4, 8]

If you want to sort by your method, there are two slight mistakes in your code: you need to decrement lst_len every time you remove an element and reinitialize min to lst[0] . 如果要按方法排序,则代码中有两个小错误:每次删除元素时都需要递减lst_len并将min重新初始化为lst[0] Also outer while should be while lst_len > 1 because list of length 1 is trivially sorted. 另外, while while应该是while lst_len > 1因为长度1的列表被简单地排序了。 Demo is given below: 演示如下:

>>> def selection_sort(lst):
   sorted = [] 
   list_len = len(lst) # Store this now because our loop will make it 
                     # smaller
   min   = lst[0]
   i     = 1
   while list_len > 1:
     while i < list_len:
       item = lst[i]
       if item < min:
         min = item
       i += 1
     lst.remove(min)
     list_len-=1   # decrement length of list
     min=lst[0]    # reinitialize min
     sorted.append(min)
   return sorted
>>> selection_sort([-8, 8, 4, -4, -2, 2]) 
[8, 4, -4, -2, 2]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM