【问题标题】:Python: Find identical items in multiple listsPython:在多个列表中查找相同的项目
【发布时间】:2010-01-22 09:36:47
【问题描述】:

我有一个任意数量的列表,例如:

[[1,2,3], [3,4,5], [5,6,7], [7,8,9]]

现在我想要一个包含多个列表中的所有元素的列表:

[3,5,7]

我该怎么做?

谢谢!

【问题讨论】:

    标签: python list


    【解决方案1】:

    与您手动操作的方式相同:

    seen = set()
    repeated = set()
    for l in list_of_lists:
      for i in set(l):
        if i in seen:
          repeated.add(i)
        else:
          seen.add(i)
    

    顺便说一句,这是一些人正在寻找的一个班轮(不计算进口)(应该比其他方法效率低)

    from itertools import *
    reduce(set.union, (starmap(set.intersection, combinations(map(set, ll), 2))))
    

    【讨论】:

    • 请小心,因为l 也需要“设置”,否则您会在 [[1,1],[2,2]] 中得到误报
    • 正如@Khelben 所说,您应该将for i in l: 更改为for i in set(l):
    • 应用@Khelben 的更正后,该解决方案运行良好。谢谢!
    • @Khelben 感谢您指出,我已经在考虑“设置模式”而不是列表 ^_^
    • 我喜欢这种方法。人们可能希望将其包装成一个函数以便于使用。
    【解决方案2】:

    最干净的方法可能是使用reduce:

    def findCommon(L):
        def R(a, b, seen=set()):
            a.update(b & seen)
            seen.update(b)
            return a
        return reduce(R, map(set, L), set())
    
    result = findCommon([[1,2,3], [3,4,5], [5,6,7], [7,8,9]])
    

    结果是一个集合,但如果你真的需要一个列表,只需执行list(result)

    【讨论】:

    • @Dyno seen 变量在调用之间包含一个“隐藏的”可变状态...函数式编程不应该依赖于副作用(如果它们不明确,这是一种危险,我敢打赌大多数人不会注意到 seen 正在扮演“静态”变量而不是常规参数的角色)
    • @fortran:R 等函数的典型用法是一次性的,因为它们被放置在另一个函数中,而不是在模块级别。我会更新答案以使其更清楚。
    • 我知道,但即使有了这个前提,粗心的读者也可能会被愚弄......我认为将seen移到R的参数列表之外并使其成为本地会更干净findCommon 的变量。
    【解决方案3】:

    这只查找所有列表共有的元素(即交集):

     set.intersection(*[set(list) for list in list_of_lists])
    

    【讨论】:

    • 当我插入原始列表时返回空集[[1,2,3], [3,4,5], [5,6,7], [7,8,9]] 我认为它的意思是所有列表的交集?
    • 我没有投入太多时间,但这不是解决 OPs 问题的方法。
    • 我已经更新了答案以澄清它只找到交叉点。
    【解决方案4】:

    参考:http://docs.python.org/library/stdtypes.html#set

    #!/usr/bin/python
    
    ll = [[1,2,3], [3,4,5], [5,6,7], [7,8,9]]
    ls = [set(l) for l in ll]
    
    su = ls[0]  #union
    ssd = ls[0] #symmetric_difference
    for s in ls[1:]:
      su = su.union(s)
      ssd = ssd.symmetric_difference(s)
    
    result = su.difference(ssd)
    print list(result)
    

    =>

    [3, 5, 7]
    

    修改并采用FP,

    ll = [[1,2,3], [3,4,5], [5,6,7], [7,8,9]]
    
    u = reduce(set.union, map(set, ll))
    sd = reduce(set.symmetric_difference, map(set, ll))
    print u - sd
    

    =>

    [3, 5, 7]
    

    【讨论】:

    • 实际上您的解决方案与我的测试用例不正确,例如lst_of_lst=[[65L, 66L, 81L, 95L, 96L, 128L, 171L, 193L, 218L, 304L, 305L, 338L, 353L, 355L, 357L, 412L], [86L, 98L, 154L, 356L], [75L, 154L], [38L, 57L, 65L, 145L, 175L, 264L, 325L, 420L, 429L, 439L], [75L, 161L], [66L, 109L, 128L, 137L, 142L, 154L, 183L, 184L, 187L, 203L, 233L, 285L, 289L, 343L]] 结果应该是[128L, 65L, 66L, 154L, 75L],但您的解决方案错过了154L
    【解决方案5】:

    试试这个:

    data = [[1,2,3], [3,4,5], [5,6,7], [7,8,9], [1,2,3]]
    
    res = set()
    
    for i in data:
        for j in data:
            if i is not j:
                res |= set(i) & set(j)
    
    print res
    

    【讨论】:

      【解决方案6】:
      >>> sets = [[1,2,3], [3,4,5], [5,6,7], [7,8,9]]
      >>> seen = set()
      >>> duplicates = set()
      >>> 
      >>> for subset in map(set, sets) :
      ...     duplicates |= (subset & seen)
      ...     seen |= subset
      ... 
      >>> print(duplicates)
      set([3, 5, 7])
      >>> 
      

      我尝试使用 map/reduce 获得单行答案,但还不能完全理解。

      【讨论】:

        【解决方案7】:

        您可以使用字典来获取每个的计数

        from collections import defaultdict
        
        init_list = [[1,2,3], [3,4,5], [5,6,7], [7,8,9]]
        #defaultdict, every new key will have a int(0) as default value
        d = defaultdict(int)
        for values in init_list:
          #Transform each list in a set to avoid false positives like [[1,1],[2,2]]
          for v in set(values):
            d[v] += 1
        
        #Get only the ones that are more than once
        final_list = [ value for value,number in d.items() if number > 1 ]
        

        【讨论】:

        • @muhuk。是的!你是绝对正确的!我已经更改了代码。 Python 的标准库真的很大,里面有很多有用的东西……
        【解决方案8】:

        我还在学习,但想分享我的答案。

        num_list1 = ['3', '6', '5', '8', '33', '12', '7', '4', '72', '2', '42', '13']
        num_list2 = ['3', '6', '13', '5', '7', '89', '12', '3', '33', '34', '1', '344', '42']
        
        result = [int(num) for num in num_list1 if num in num_list2)
        print(result)
        

        打印出来:

        [3, 6, 5, 33, 12, 7, 42, 13]
        

        比较两个列表中的所有元素并创建一个包含相似元素的新列表。并将它们变成整数。

        【讨论】:

          【解决方案9】:
          l=[[1,2,3], [3,4,5], [5,6,7], [7,8,9]]
          d={}
          for x in l:
              for y in x:
                  if not d.has_key(y):
                      d[y]=0
                  d[y]+=1
          [x for x,y in d.iteritems() if y>1]
          

          【讨论】:

            【解决方案10】:

            这是我的出发点:

            seen = set()
            result = set()
            for s in map(set, [[1,2,3], [3,4,5], [5,6,7], [7,8,9]]):
                result.update(s & seen)
                seen.update(s)
            print result
            

            打印出来:

            set([3, 5, 7])
            

            【讨论】:

              【解决方案11】:

              您可以使用一组请参阅http://docs.python.org/library/stdtypes.html#set

              【讨论】:

                【解决方案12】:

                扁平化、排序、1 for循环比较前后数字

                【讨论】:

                • 如果一个数字在同一个列表中出现两次,这将失败。
                • 如果你先展平,你会得到一个“误报”的输入,例如:[[1, 1], [2, 2]]
                猜你喜欢
                • 2011-08-03
                • 1970-01-01
                • 2020-07-10
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2021-12-24
                • 2017-01-31
                相关资源
                最近更新 更多