【问题标题】:Merge List of lists where sublists have common elements合并子列表具有共同元素的列表列表
【发布时间】:2012-10-04 10:18:41
【问题描述】:

我有一个这样的列表列表

list = [[1, 2], [1, 3], [4, 5]]

如你所见,前两个子列表的第一个元素重复了

所以我也希望我的输出是:

list = [[1, 2, 3], [4, 5]]

谢谢

【问题讨论】:

    标签: python list merge


    【解决方案1】:

    以下代码应该可以解决您的问题:

    def merge_subs(lst_of_lsts):
        res = []
        for row in lst_of_lsts:
            for i, resrow in enumerate(res):
                if row[0]==resrow[0]:
                    res[i] += row[1:]
                    break
            else:
                res.append(row)
        return res
    

    请注意,else 属于内部 for,如果在退出循环时没有遇到中断,则会执行。

    【讨论】:

      【解决方案2】:

      我有一个解决方案,它首先使用第一个值构建一个 dict,然后从中创建一个列表,但顺序可能不一样(即 [4, 5] 可能在 [1, 2, 3] 之前):

      >>> from collections import defaultdict
      >>> d = defaultdict(list)
      >>> map(lambda x: d[x[0]].append(x[1]), l)
      [None, None, None]
      >>> d
      defaultdict(<type 'list'>, {1: [2, 3], 4: [5]})
      >>> [[key] + list(val) for key, val in d.iteritems()]
      [[1, 2, 3], [4, 5]]
      

      【讨论】:

        【解决方案3】:

        您可以使用 python 集合,因为您可以很容易地计算交集和并集。代码会更清晰,但复杂度可能与其他解决方案相当。

        【讨论】:

          【解决方案4】:

          虽然可以说是不可读:

          # Note the _ after the list, otherwise you are redefining the list type in your scope
          list_ = [[1, 2], [1, 3], [4, 5]]
          
          from itertools import groupby
          grouper = lambda l: [[k] + sum((v[1::] for v in vs), []) for k, vs in groupby(l, lambda x: x[0])]
          
          print grouper(list_)
          

          更易读的变体:

          from collections import defaultdict
          groups = defaultdict(list)
          for vs in list_:
              group[vs[0]] += vs[1:]
          
          print group.items()
          

          请注意,这些解决了您的问题的更通用形式,而不是 [[1, 2], [1, 3], [4, 5]],您还可以使用以下内容:[[1, 2, 3], [1, 4, 5], [2, 4, 5, 6], [3]]


          关于_的解释。这就是你不想覆盖list的原因:

          spam = list()
          print spam
          # returns []
          
          list = spam
          print list
          # returns []
          
          spam = list()
          # TypeError: 'list' object is not callable
          

          正如您在上面看到的,通过设置list = spam,我们打破了list() 的默认行为。

          【讨论】:

          • @user1422056:_ 后缀是默认约定,以防止名称与其他变量发生冲突。由于 list 已经存在于 Python 中,因此通常使用 list_ 代替。 delwithfor 等也是如此。
          猜你喜欢
          • 2017-10-17
          • 2018-04-29
          • 2011-06-18
          • 1970-01-01
          • 2021-03-15
          • 2016-01-21
          • 1970-01-01
          相关资源
          最近更新 更多