【问题标题】:Identify duplicate values in a list in Python在 Python 中识别列表中的重复值
【发布时间】:2023-08-20 09:43:02
【问题描述】:

是否可以使用 python 获取列表中的重复值?

我有一个物品清单:

    mylist = [20, 30, 25, 20]

我知道删除重复项的最佳方法是set(mylist),但是是否有可能知道哪些值被重复了?如您所见,在此列表中,重复项是第一个和最后一个值。 [0, 3].

是否有可能在 python 中得到这个结果或类似的东西?我试图避免做出一个可笑的大if elif 条件语句。

【问题讨论】:

标签: python arrays list


【解决方案1】:

这些答案是 O(n),因此比使用 mylist.count() 的代码要多一些,但随着 mylist 变长,效率会更高

如果您只想知道重复项,请使用 collections.Counter

from collections import Counter
mylist = [20, 30, 25, 20]
[k for k,v in Counter(mylist).items() if v>1]

如果您需要了解索引,

from collections import defaultdict
D = defaultdict(list)
for i,item in enumerate(mylist):
    D[item].append(i)
D = {k:v for k,v in D.items() if len(v)>1}

【讨论】:

  • 您可以使用更紧凑的 [i for key in (key for key, count in Counter(mylist).items() if count > 1) for i, x in enumerate(mylist) if x == key] 来做到这一点 - 虽然它有点像怪物,但您可能想要分离出生成器表达式。
  • 你可以创建def indices(seq, values):return (i for value in values for i, x in enumerate(seq) if x == value),然后创建indices(mylist, (key for key, count in Counter(mylist).items() if count > 1)。这非常简洁(当不塞进评论时)。
【解决方案2】:

这是一个列表理解,可以满足您的需求。正如@Codemonkey 所说,列表从索引 0 开始,因此重复项的索引是 0 和 3。

>>> [i for i, x in enumerate(mylist) if mylist.count(x) > 1]
[0, 3]

【讨论】:

  • 这是 O(n^2)... 你可以做得更好。
  • @Levon,它会搜索整个列表
  • 对于那些不理解 O(N^2) 含义的人:这意味着对于 10 个元素的列表,您将执行 100 个步骤,对于 1000 个元素,100 万个步骤,对于 1一百万个元素一百万步等。二次性能会很快杀死你的性能。
【解决方案3】:

以下列表推导将产生重复值:

[x for x in mylist if mylist.count(x) >= 2]

【讨论】:

  • 这给出了重复的值,而不是它们的索引
  • @Junuxx:虽然他确实提到了索引,但他要求的是值,而不是索引。
  • “如您所见,在此列表中,重复项是第一个和最后一个值。[0, 3]”似乎表示所需的输出。
  • @Swiss 不,不是。集合推导只需要花括号,这里的括号完全没用。
  • @Swiss 我不是母语人士,随着时间的推移,我学会了[ ->(方)括号,( -> 括号,{ ->(大括号)美国.. :)
【解决方案4】:

您可以使用列表压缩和设置来降低复杂度。

my_list = [3, 5, 2, 1, 4, 4, 1]
opt = [item for item in set(my_list) if my_list.count(item) > 1]

【讨论】:

    【解决方案5】:

    使用 list.index() 没有任何中间列表的最简单方法:

    z = ['a', 'b', 'a', 'c', 'b', 'a', ]
    [z[i] for i in range(len(z)) if i == z.index(z[i])]
    >>>['a', 'b', 'c']
    

    您还可以列出重复项本身(可能再次包含重复项,如示例中所示):

    [z[i] for i in range(len(z)) if not i == z.index(z[i])]
    >>>['a', 'b', 'a']
    

    或他们的索引:

    [i for i in range(len(z)) if not i == z.index(z[i])]
    >>>[2, 4, 5]
    

    或作为索引的 2 元组列表的重复项(仅引用它们的第一次出现),原始问题的答案是什么!!!

    [(i,z.index(z[i])) for i in range(len(z)) if not i == z.index(z[i])]
    >>>[(2, 0), (4, 1), (5, 0)]
    

    或者这个和项目本身一起:

    [(i,z.index(z[i]),z[i]) for i in range(len(z)) if not i == z.index(z[i])]
    >>>[(2, 0, 'a'), (4, 1, 'b'), (5, 0, 'a')]
    

    或任何其他元素和索引的组合......

    【讨论】:

      【解决方案6】:

      我尝试下面的代码从列表中查找重复值

      1) 创建一组重复列表

      2) 通过查看重复列表来迭代集合。

      glist=[1, 2, 3, "one", 5, 6, 1, "one"]
      x=set(glist)
      dup=[]
      for c in x:
          if(glist.count(c)>1):
              dup.append(c)
      print(dup)
      

      输出

      [1, '一']

      现在获取重复元素的所有索引

      glist=[1, 2, 3, "one", 5, 6, 1, "one"]
      x=set(glist)
      dup=[]
      for c in x:
          if(glist.count(c)>1):
              indices = [i for i, x in enumerate(glist) if x == c]
              dup.append((c,indices))
      print(dup)
      

      输出

      [(1, [0, 6]), ('one', [3, 7])]

      希望这对某人有所帮助

      【讨论】:

        【解决方案7】:

        这是我能想到的在列表中查找重复项的最简单方法:

        my_list = [3, 5, 2, 1, 4, 4, 1]
        
        my_list.sort()
        for i in range(0,len(my_list)-1):
                       if my_list[i] == my_list[i+1]:
                           print str(my_list[i]) + ' is a duplicate'
        

        【讨论】:

        • 如果项目出现两次以上,您将打印多次。
        【解决方案8】:

        以下代码将使用重复项及其索引值获取您想要的结果。

          for i in set(mylist):
            if mylist.count(i) > 1:
                 print(i, mylist.index(i))
        

        【讨论】:

          【解决方案9】:

          您应该对列表进行排序:

          mylist.sort()
          

          之后,像这样遍历它:

          doubles = []
          for i, elem in enumerate(mylist):
              if i != 0:
                  if elem == old:
                      doubles.append(elem)
                      old = None
                      continue
              old = elem
          

          【讨论】:

          • 这没有得到询问者似乎想要的项目索引。此外,在 Python 中创建一个空列表并循环遍历项目以附加一些内容是一种反模式,请使用列表推导式。
          • 这也将打印多次出现超过两次的项目。
          【解决方案10】:

          您可以使用以下逻辑使用列表打印重复和 Unqiue。

          def dup(x):
              duplicate = []
              unique = []
              for i in x:
                  if i in unique:
                      duplicate.append(i)
                  else:
                      unique.append(i)
              print("Duplicate values: ",duplicate)
              print("Unique Values: ",unique)
          
          list1 = [1, 2, 1, 3, 2, 5]
          dup(list1)
          

          【讨论】:

            【解决方案11】:
            mylist = [20, 30, 25, 20]
            
            kl = {i: mylist.count(i) for i in mylist if mylist.count(i) > 1 }
            
            print(kl)
            

            【讨论】:

              【解决方案12】:

              看起来您想要重复项的索引。下面是一些短代码,可以在 O(n) 时间内找到它们,而无需使用任何包:

              dups = {}
              [dups.setdefault(v, []).append(i) for i, v in enumerate(mylist)]
              dups = {k: v for k, v in dups.items() if len(v) > 1}
              # dups now has keys for all the duplicate values
              # and a list of matching indices for each
              
              # The second line produces an unused list. 
              # It could be replaced with this:
              for i, v in enumerate(mylist):
                  dups.setdefault(v, []).append(i)
              

              【讨论】:

                【解决方案13】:
                m = len(mylist)
                for index,value in enumerate(mylist):
                        for i in xrange(1,m):
                                if(index != i):
                                    if (L[i] == L[index]):
                                        print "Location %d and location %d has same list-entry:  %r" % (index,i,value)
                

                这有一些冗余,但是可以改进。

                【讨论】:

                  【解决方案14】:
                  def checkduplicate(lists): 
                   a = []
                   for i in lists:
                      if  i in a:
                          pass   
                      else:
                          a.append(i)
                   return i          
                              
                  print(checkduplicate([1,9,78,989,2,2,3,6,8]))
                  

                  【讨论】:

                  • 这会打印出列表中的最后一个值。即使您将其更正为return a,也会删除重复项,但问题是“是否有可能知道哪些值被重复了