在python 2.7中搜索列表中的重复值

时间:2017-01-25 21:59:30

标签: python python-2.7 list loops

list1 = ["green","red","yellow","purple","Green","blue","blue"]

所以我得到了一个列表,我想循环遍历列表,看看是否多次提到颜色。如果有,它不会附加到新列表。

所以你应该留下

list2 = ["red","yellow","purple"]

所以我试过这个

list1 = ["green","red","yellow","purple","Green","blue","blue","yellow"]
list2 =[]
num = 0
for i in list1:
    if (list1[num]).lower == (list1[i]).lower:
        num +=1
    else:
        list2.append(i)
        num +=1

但我一直收到错误

5 个答案:

答案 0 :(得分:2)

使用Counterhttps://docs.python.org/2/library/collections.html#collections.Counter

from collections import Counter
list1 = ["green","red","yellow","purple","green","blue","blue","yellow"]
list1_counter = Counter([x.lower() for x in list1])
list2 = [x for x in list1 if list1_counter[x.lower()] == 1]

请注意,您的示例有误,因为yellow存在两次。

答案 1 :(得分:1)

第一个问题是for i in list1:遍历列表中的元素而不是索引,所以使用i你有一个元素你的手。

接下来有num这是一个索引,但你似乎以错误的方式递增它。

我建议您使用以下代码:

for i in range(len(list1)):
    unique = True
    for j in range(len(list1)):
        if i != j and list1[i].lower() == list1[j].lower():
            unique = False
            break
    if unique:
        list2.append(list1[i])

这是如何工作的:此处ij索引,您遍历列表并使用i迭代元素的索引可能想要添加,现在你做一个测试:你检查列表中的某个地方是否看到另一个相等的元素。如果是,请将unique设置为False并为下一个元素执行,否则添加。

您还可以使用for - else这样的结构,如@YevhenKuzmovych所说:

for i in range(len(list1)):
    for j in range(len(list1)):
        if i != j and list1[i].lower() == list1[j].lower():
            break
    else:
        list2.append(list1[i])

您可以使用any

使代码更加优雅
for i in range(len(list1)):
    if not any(i != j and list1[i].lower() == list1[j].lower() for j in range(len(list1))):
        list2.append(list1[i])

现在这更优雅,但仍然效率不高。为了提高效率,您可以使用Counter

from collections import Counter

ctr = Counter(x.lower() for x in list1)

构建完计数器后,查看元素的次数,如果小于2,则将其添加到列表中:

from collections import Counter

ctr = Counter(x.lower() for x in list1)

for element in list1:
    if ctr[element.lower()] < 2:
        list2.append(element)

最后,你现在甚至可以使用 list comprehension 来使它非常优雅:

from collections import Counter

ctr = Counter(x.lower() for x in list1)

list2 = [element for element in list1 if ctr[element.lower()] < 2]

答案 2 :(得分:1)

这是另一个解决方案:

list2 = []
for i, element in enumerate(list1):
    if element.lower() not in [e.lower() for e in list1[:i] + list1[i + 1:]]:
        list2.append(element)

答案 3 :(得分:1)

通过组合内置插件,您只需保留唯一的项目保留外观顺序,只需一个空类定义和一个单行:

from future_builtins import map  # Only on Python 2 to get generator based map
from collections import Counter, OrderedDict

class OrderedCounter(Counter, OrderedDict):
    pass

list1 = ["green","red","yellow","purple","Green","blue","blue"]

# On Python 2, use .iteritems() to avoid temporary list
list2 = [x for x, cnt in OrderedCounter(map(str.lower, list1)).items() if cnt == 1]

# Result: ['red', 'yellow', 'purple']

您使用Counter功能来计算可迭代次数,而继承自OrderedDict会保留关键顺序。您所要做的就是过滤结果以检查和去除计数,从而显着降低代码复杂性。

它还将工作减少到原始list的一次传递,第二次传递与list中的唯一项目数量成比例,而不是必须执行两次传递原始list(如果重复是常见且list很大,则很重要)。

答案 4 :(得分:0)

这是另一种解决方案......

首先,在我开始之前,我认为有一个错字......你有&#34;黄色&#34;列出两次,你指定你最后有黄色。所以,为此,我将提供两个脚本,一个允许重复,一个不包含。

原件:

list1 = ["green","red","yellow","purple","Green","blue","blue","yellow"]
list2 =[]
num = 0
for i in list1:
    if (list1[num]).lower == (list1[i]).lower:
        num +=1
    else:
        list2.append(i)
        num +=1

已修改(允许重复):

colorlist_1 = ["green","red","yellow","purple","Green","blue","blue","yellow"]
colorlist_2 = []
seek = set()

i = 0
numberOfColors = len(colorlist_1)

while i < numberOfColors:
    if numberOfColors[i].lower() not in seek:
        seek.add(numberOfColors[i].lower())
        colorlist_2.append(numberOfColors[i].lower())

    i+=1

print(colorlist_2)

# prints ["green","red","yellow","purple","blue"]

已修改(不允许重复):

修改

Willem Van Onsem的答案完全适用且已经彻底。