简体   繁体   English

Python,从列表中删除重复项

[英]Python, removing duplicates from a list

I suppose the Pythonic way is to use set, which I just learned about. 我想Pythonic的方法是使用我刚学过的set。 Before I learned about set, I tried the following method which didn't work. 在学习set之前,我尝试了以下无效的方法。 Can someone explain what is wrong with this? 有人可以解释这是怎么回事吗? I got an index out of range error, but I thought the code would never run past the index range for the list as it is written. 我收到索引超出范围的错误,但是我认为代码在编写时永远不会超出列表的索引范围。 Please explain what happened. 请解释发生了什么。

#!/usr/bin/python
# Remove dupes from a list
def Uniq_list(x):
  for elem in range(len(x)):
    if ( elem == 0 ):
      next
    else:
      if (x[elem] == x[(elem - 1)]):
        x.pop(index(x[elem])
  return x

mylist = ['1', '1', '2', '1', '3', '2']

print Uniq_list(mylist)

The for loop produces the range() object just once, but in the loop you are removing elements from the list, making it shorter. for循环仅生成一次range()对象,但是在循环中,您将从列表中删除元素,使其更短。

This leads to another problem: you'll be skipping elements. 这导致了另一个问题:您将跳过元素。 If you remove element 1, all elements after it shift up one position; 如果删除元素1,则其后的所有元素将上移一个位置; element 2 is now element 1, etc. But your loop never takes this into account, so it'll skip the element now moved from position 2 to 1. 元素2现在是元素1,依此类推。但是您的循环永远不会考虑到这一点,因此它将跳过现在从位置2移到位置1的元素。

This is compounded by the fact you only use the preceding element to test set membership against; 由于您仅使用前面的元素来测试集合成员资格,这一事实使情况更加复杂。 the skipped element is suddenly the value against which another value is being tested. 跳过的元素突然是正在测试另一个值的值。 They could well be different but that doesn't mean earlier elements are not going to be equal. 它们可能会有所不同,但这并不意味着早期的元素将不相等。

Further issues: You used an unnamed index() function in your code which means we cannot verify what it does. 进一步的问题:您在代码中使用了一个未命名的index()函数,这意味着我们无法验证它的作用。 If it works like the list.index() method you'd be removing the first occurrence of the value from the list object. 如果它像list.index()方法一样工作, list.index()从列表对象中删除第一次出现的值。 This could work, but you already had elem as an index into the list, why search for it again? 这可能有效,但是您已经有了elem作为列表的索引,为什么还要再次搜索呢?

The next entry on it's own line is just a reference to the next() function , without ever calling it. 它自己的行上的next条目只是对next()函数的引用,而无需调用它。 As such, it is a no-op. 因此,这是无人操作。 You probably meant to use the continue statement here instead. 您可能打算在此处使用continue语句

A simpler version would have been: 一个更简单的版本是:

for i in range(len(x), -1, -1):
    if x[i] in x[:i]:
        del x

eg starting from the end of the list, if the current element is present in the list before this position, remove it. 例如,从列表末尾开始,如果当前元素在列表中此位置之前 ,则将其删除。 However, using a set would be far more efficient still. 但是,使用集合仍然会更加有效。

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

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