【问题标题】:Merging elements in 2D list based on common first elements基于共同的第一个元素合并二维列表中的元素
【发布时间】:2020-06-19 07:10:00
【问题描述】:

给定以下列表:

lst = [[3,5],[3,10],[3,15],[3,102],[5,21],[5,23],[5,50]]

我想获得以下 [[3,5,10,15,102], [5,21,23,50]]

请注意,列表是根据第一个元素的值升序排序的。

这样做最有效的方法是什么?这就是我的想法:

第 1 步:创建一个包含唯一第一个元素的列表。 (即本例中的 3 和 5)

first_elements = [] #initialize empty list to which we will append all first elements
for i in range(len(lst)):
    first_elements.append(lst[i][0])
first_elements = list(set(first_elements)) #Filter out the unique first elements
    first_elements = [3,5]

第 2 步:根据第一个元素过滤 lst。将这些附加到新列表中。

new_merged_list = [] # create new list to append to
for i in range(len(first_elements)): 
    first_element_to_filter_by = first_elements[i]
    filtered_2d_list           = [i for i in lst if i[0] == first_element_to_filter_by]
    new_merged_list.append([first_element_to_filter_by])

    for j in range(len(filtered_2d_list)):
        (new_merged_list[i]).append(filtered_2d_list[j][1])    

这给了我正确的答案,如下所示。

new_merged_list = [[3, 5, 10, 15, 102], [5, 21, 23, 50]]

我的问题 - 有没有更有效的方法来做到这一点?我不知道这将如何扩展到(例如)100000 x 2 的列表。

感谢您的帮助!

【问题讨论】:

    标签: python python-3.x list optimization merge


    【解决方案1】:

    您可以在此处使用defaultdict。即使您的 lst 未排序,这也将起作用。

    from collections import defaultdict
    new = defaultdict(list)
    lst = [[3, 5], [3, 10], [3, 15], [3, 102], [5, 21], [5, 23], [5, 50]]
    
    for k,v in lst:
        new[k].append(v)
    
    new = [[k]+v for k,v in new.items()]
    # [[3, 5, 10, 15, 102], [5, 21, 23, 50]]
    # Or 
    new = [[k,*v] for k,v in new.items()]
    # [[3, 5, 10, 15, 102], [5, 21, 23, 50]]
    

    【讨论】:

    • @user3424575 即使lst 未排序,这也将起作用。很高兴为您提供帮助。
    • 我唯一想补充的是,在构建最终列表时,您应该遍历 lst,而不是 new,因为根据 Python 的版本,键的顺序可能不会被保留,您可能会在 [3, ...] 部分之前得到 [5, ...] 部分
    • @ChatterOne 是的,python3.7以上的字典键保持添加顺序。
    【解决方案2】:

    你可以做这样的事情(不导入模块)

    first_elements = list(set([item[0] for item in lst]))
    result = [[elem] for elem in first_elems]
    for sublist in lst:
        result[first_elems.index(sublist[0])].append(sublist[1])
    

    【讨论】:

      【解决方案3】:
      # seems to work - assuming the initial sorting as stated
      
      result = []
      
      prv_first = None
      for sub_lst in lst:
          first = sub_lst[0]
          if first != prv_first:
              prv_first = first
              cur_list = [] + sub_lst
              result.append(cur_list)
          else:
              cur_list.extend(sub_lst[1:])
      

      【讨论】:

        【解决方案4】:

        一次通过。

        lst = [[3,5],[3,10],[3,15],[3,102],[5,21],[5,23],[5,50]]
        
            current = None
            ret = []
            for i in lst:
                if i[0] == current:
                    ret[-1].append(i[1])
                else:
                    current = i[0]
                    ret.append([current])
                    ret[-1].append(i[1])
        
        # [[3, 5, 10, 15, 102], [5, 21, 23, 50]]
        

        【讨论】:

          【解决方案5】:

          一行:

          a = np.array([[0, 0], [0, 3], [0, 4], [1, 1], [2, 2], [3, 0], [3, 3], [3, 4], [4, 0], [4, 3], [4, 4]])
          
          result = [[i]+a[a[:, 0] == i, 1].tolist() for i in np.unique(a[:, 0])]
          
          print(result)
          

          【讨论】:

            猜你喜欢
            • 2013-09-25
            • 2023-03-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-12-05
            • 2019-07-15
            • 2011-06-18
            相关资源
            最近更新 更多