【问题标题】:python: combine each element of a list to a list of tuple [closed]python:将列表的每个元素组合到元组列表[关闭]
【发布时间】:2021-09-09 08:43:35
【问题描述】:

我有一个数字列表:

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

我还有另一个元组列表:

list_B = [(10, 11), (20,21), (30,31), (40,41), (50,51)]

我想合并list_A和list_B,变成下面这样:

[(10,11,1), (20,21,2), (30,31,3), (40,41,4), (50,51,5)]

这样做最有效的方法是什么?

【问题讨论】:

  • 请将您自己尝试解决此问题的代码编辑到您的问题中,并显示输出有什么问题。
  • 迭代列表,并将list_A中的元素添加到list_B中对应的元组中。你可以试试[(*list_B[i], list_A[i]) for i in range(len(list_A))]

标签: python list combinations


【解决方案1】:

双拉链:

[*zip(*zip(*list_B), list_A)]

目前解决方案的比较:

1035 ns  1047 ns  1049 ns  [(*b, a) for a, b in zip(list_A, list_B)]
1138 ns  1140 ns  1141 ns  [(list_B[index][0], list_B[index][1], list_A[index]) for index in range(len(list_A))]
 963 ns   967 ns   993 ns  [list_B[i] + (list_A[i],) for i in range(len(list_A))]
 805 ns   820 ns   826 ns  [i + (j,) for j,i in zip(list_A,list_B)]
 947 ns   952 ns   965 ns  [*zip(*zip(*list_B), list_A)]

基准代码(Try it online!):

from timeit import repeat

list_A = [1, 2, 3, 4, 5]
list_B = [(10, 11), (20, 21), (30, 31), (40, 41), (50, 51)]

E = [
    '[(*b, a) for a, b in zip(list_A, list_B)]',
    '[(list_B[index][0], list_B[index][1], list_A[index]) for index in range(len(list_A))]',
    '[list_B[i] + (list_A[i],) for i in range(len(list_A))]',
    '[i + (j,) for j,i in zip(list_A,list_B)]',
    '[*zip(*zip(*list_B), list_A)]',
]

for _ in range(3):
    for e in E:
        number = 100000
        times = sorted(repeat(e, globals=globals(), number=number, repeat=3))
        print(*('%4d ns ' % (t / number * 1e9) for t in times), e)
    print()

【讨论】:

  • 基准测试可能对超过 5 个元素的列表更有洞察力!
  • @Stef 也许,也许不是。取决于他们是否有更长的列表或在许多短列表中这样做。我曾经写过一个 O(n) 解决方案,而一个 O(n^2) 解决方案却被接受了,因为事实证明 OP 实际上只有类似的小列表,而 O(n^2) 解决方案在这些方面要快一些。
  • @Stef One 可能还需要更长的内部元组。或两者。所以这是两个不同的维度。在这种情况下,我倾向于不猜测,并且我不想包括四个基准(甚至更多,对于小/中/大尺寸)。但是基准代码就在那里,如果需要,应该很容易调整。
【解决方案2】:

使用列表推导来解包和重新打包元素,并将列表放在一起进行迭代,您可以使用zip

list_A = [1, 2, 3, 4, 5]
list_B = [(10, 11), (20, 21), (30, 31), (40, 41), (50, 51)]

output = [(*b, a) for a, b in zip(list_A, list_B)]

>>> [(10, 11, 1), (20, 21, 2), (30, 31, 3), (40, 41, 4), (50, 51, 5)]

【讨论】:

    【解决方案3】:

    使用zip

    res = [i + (j,) for j,i in zip(list_A,list_B)]
    

    输出:

    [(10, 11, 1), (20, 21, 2), (30, 31, 3), (40, 41, 4), (50, 51, 5)]
    

    【讨论】:

      【解决方案4】:

      如果list_B 中的元组总是包含 2 个项目,那么这样解包会更清晰、更快捷:

      [(a, b, c) for (a, b), c in zip(list_B, list_A)]
      

      借用@don'ttalkjustcode 的基准代码:

      1091 ns  1109 ns  1109 ns  [(*b, a) for a, b in zip(list_A, list_B)]
      1183 ns  1189 ns  1205 ns  [(list_B[index][0], list_B[index][1], list_A[index]) for index in range(len(list_A))]
      1035 ns  1052 ns  1053 ns  [list_B[i] + (list_A[i],) for i in range(len(list_A))]
       843 ns   897 ns   926 ns  [i + (j,) for j,i in zip(list_A,list_B)]
       979 ns   994 ns  1015 ns  [*zip(*zip(*list_B), list_A)]
       760 ns   765 ns   767 ns  [(a, b, c) for (a, b), c in zip(list_B, list_A)]
      

      Try it online!

      【讨论】:

        【解决方案5】:

        对于 B 的每个元素(一个元组),您将 A 的每个元素添加到元组中。请注意,这只有在 A 的元素是元组时才有可能,因此需要括号和逗号。

        使用列表推导:

        list_A = [1,2,3,4,5]
        list_B = [(10, 11), (20,21), (30,31), (40,41), (50,51)]
        
        [list_B[i] + (list_A[i],) for i in range(len(list_A))]   
        

        输出:

        Out[16]: [(10, 11, 1), (20, 21, 2), (30, 31, 3), (40, 41, 4), (50, 51, 5)]
        

        【讨论】:

        • 您应该避免在可迭代对象中使用range(len(list_A)) 和索引,而是直接遍历对象。它更 Pythonic,而且通常也更快。
        【解决方案6】:
        res = [(list_B[index][0], list_B[index][1], list_A[index]) for index in range(len(list_A))])
        

        输出:

        [(10, 11, 1), (20, 21, 2), (30, 31, 3), (40, 41, 4), (50, 51, 5)]
        

        【讨论】:

          【解决方案7】:

          你可以使用 for 循环来做到这一点

          数字列表:

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

          数字的元组列表:

          list_b = [(10, 11), (20, 21), (30, 31), (40, 41), (50, 51)]
          

          如您所知,元组是不可变的
          因此,您可以创建一个空列表:

          new_list = []
          

          让我们运行一个循环来解决:

          for i in range(len(list_a)):
                  list_together = []
                  list_together += list_b[i]
                  list_together.append(list_a[i])
                  tup = tuple(list_together)
                  new_list.append(tup)
          

          详情:

          • list_a 的范围/长度内运行循环
          • list_together 连接 list_alist_b
          • 循环运行时在list_together 变量中附加list-a 值和list_b
          • tup 将列表转换为元组,然后附加到 new_list

          最后,让我们打印新创建的列表作为输出:

          print(new_list)
          

          输出:

          [(10, 11, 1), (20, 21, 2), (30, 31, 3), (40, 41, 4), (50, 51, 5)]
          

          【讨论】:

          • for 循环内的连接比使用列表推导式更慢且更少 Pythonic。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-08-24
          • 1970-01-01
          • 1970-01-01
          • 2016-12-19
          • 2020-05-22
          • 1970-01-01
          相关资源
          最近更新 更多