【问题标题】:Comparing `list`s in python比较python中的`list`
【发布时间】:2011-02-11 02:23:13
【问题描述】:

我有多个列表。与所有列表相比,我需要找到一种方法来生成每个列表中的唯一项目列表。有没有简单或直接的方法来做到这一点。我知道这些列表基本上可以用作sets。

【问题讨论】:

  • 使用set(),还需要什么?
  • 那么对于每个列表,您想找到它的元素,而不是在任何其他列表中?
  • 除了“set()”之外,还有更多的逻辑可以找出每个列表的独特之处。
  • 我认为他/她的意思是“对于每个列表,生成该列表中出现的项目,但没有其他项目。”
  • @phooji 是正确的,很抱歉我之前没有说清楚。

标签: python list unique set


【解决方案1】:
import collections

def uniques(*args):
    """For an arbitrary number of sequences,
           return the items in each sequence which
            do not occur in any of the other sequences
    """

    # ensure that each value only occurs once in each sequence
    args = [set(a) for a in args]

    seen = collections.defaultdict(int)
    for a in args:
        for i in a:
            seen[i] += 1
    # seen[i] = number of sequences in which value i occurs

    # for each sequence, return items
    #  which only occur in one sequence (ie this one)
    return [[i for i in a if seen[i]==1] for a in args]

所以

uniques([1,1,2,3,5], [2,3,4,5], [3,3,3,9])  ->  [[1], [4], [9]]

【讨论】:

  • 小说。但是使用 set API 更像 Pythonic,你不觉得吗?
  • @santa:除了这样可以避免组合 (n-1) 个集合的所有可能组合。
【解决方案2】:

使用集合类和其中定义的集合操作:

>>> l1 = [1,2,3,4,5,5]
>>> l2 = [3,4,4,6,7]
>>> set(l1) ^ set(l2)    # symmetric difference
set([1, 2, 5, 6, 7])

edit:啊,误读了你的问题。如果您的意思是“l1 中的唯一元素不在任何l2, l3, ..., ln 中,那么:

l1set = set(l1)
for L in list_of_lists:   # list_of_lists = [l2, l3, ..., ln]
    l1set = l1set - set(L)

【讨论】:

    【解决方案3】:
    l1 = [4, 6, 3, 7]
    l2 = [5, 5, 3, 1]
    l3 = [2, 5, 4, 3]
    l4 = [9, 8, 7, 6]
    
    # first find the union of the "other" lists
    l_union = reduce(set.union, (map(set, (l1, l2, l3))))
    
    # then subtract the union from the remaining list
    uniques = set(l4) - l_union
    
    print uniques
    

    结果:

    >>> set([8, 9])
    

    【讨论】:

    • 对于 n 个输入列表,您必须重复此过程 n 次(l1 的项目不在 l2,l3,l4 中,l2 的项目不在 l1,l3,l4 中,l3 的项目不在 l1 中, l2,l4, l4 中的项目不在 l1,l2,l3)。
    【解决方案4】:
    for l in lists:
      s = set(l)
      for o in lists:
        if o != l:
          s -= set(o)
    
      # At this point, s holds the items unique to l
    

    为了提高效率,您可以一次将所有列表转换为集合。

    【讨论】:

      【解决方案5】:
      import itertools
      
      # Test set
      lists = []
      lists.append([1,2,3,4,5,5])
      lists.append([3,4,4,6,7])
      lists.append([7,])
      lists.append([8,9])
      lists.append([10,10])
      
      # Join all the lists removing the duplicates in each list
      join_lists = []
      for list_ in lists:
          join_lists.extend(set(list_))
      
      # First, sort
      join_lists.sort()
      
      # Then, list only the groups with one element
      print [ key for key, grp in itertools.groupby(join_lists) if len(list(grp)) < 2 ]
      
      #>>> [1, 2, 6, 8, 9]
      
      ###
      

      【讨论】:

      • 如果一个组包含一个值的多个实例(即 4),即使没有其他组包含它,它也会被取消资格。
      猜你喜欢
      • 2021-12-26
      • 1970-01-01
      • 1970-01-01
      • 2011-12-20
      • 2023-02-06
      • 2018-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多