【问题标题】:How do you merge two lists and return them as a tuple in a new list?如何合并两个列表并将它们作为新列表中的元组返回?
【发布时间】:2021-12-15 13:16:51
【问题描述】:

规则:如果一个列表比另一个短,则较短列表的最后一个元素应尽可能多地重复。如果一个或两个列表为空,则应返回空列表。

合并([0, 1, 2], [5, 6, 7])

应该返回 [(0, 5), (1, 6), (2, 7)]

合并([2, 1, 0], [5, 6])

应该返回 [(2, 5), (1, 6), (0, 6)]

合并([ ], [2, 3])

应该返回 []

这是我到目前为止写的内容

def merge(a, b):
mergelist = []
for pair in zip(a, b):
    for item in pair :
        mergelist.append(item )
return mergelist

打印(合并([0, 1, 2], [5, 6]))

【问题讨论】:

  • 使用内置函数zip
  • 你只是在list(zip(a, b))之后吗?
  • zip 已经在他的代码中。而且预期的结果有点奇怪
  • 那么,您希望输出具有第一个列表的长度,如果第二个列表的最后一项更短,那么它会重复?如果它是空的怎么办?或者是别的什么?请澄清规则。
  • 如果一个列表比另一个短,则较短列表的最后一个元素应根据需要重复。如果一个或两个列表为空,则应返回空列表。

标签: python list merge tuples


【解决方案1】:

感谢您提出问题。 我试图修改你的代码,因为它总是更容易理解我们自己的代码。 请查找修改

def merge(a, b):
    mergelist = []
    if not a or not b:
        return []
    elif len(a) > len(b):
        occ = len(a)-len(b)
        b.extend([b[len(b)-1] for i in range(occ)])
    elif len(a) < len(b):

        occ = len(b)-len(a)
        a.extend([a[len(a)-1] for i in range(occ)])

    for pair in zip(a, b):
        mergelist.append(pair)
    return mergelist

print(merge(l,l1))

【讨论】:

    【解决方案2】:

    您需要手动附加返回列表中的每个元组,因为您需要检查第二个列表的长度是否相应。这是解决这个问题的一种方法

    def merge(l1, l2):
        new = []
        for i in range(len(l1)):
            if i > len(l2)-1:
                s2 = l2[len(l2)-1] # use the last element of second list if there are no more elements
            else:
                s2 = l2[i]
            new.append(l1[i], s2)
        return new
    
    """
    >>> merge([0,1,2],[5,6,7])
    [(0, 5), (1, 6), (2, 7)]
    >>> merge([2,1,0],[5,6])
    [(2, 5), (1, 6), (0, 6)]
    >>> merge([],[2,3])
    []
    """
    

    【讨论】:

      【解决方案3】:

      这实际上有点棘手。 你会认为像这样简单的事情会起作用:

      def merge(a, b):
          # use iterator to keep iterations state after zip
          a, b = iter(a), iter(b)
          rtrn = list(zip(a, b))
          try:
              taila, tailb = rtrn[-1]
          except IndexError: # one or both empty
              return rtrn
          # only one of these loops will run, draining the longer input list
          rtrn.extend((ai, tailb) for ai in a)
          rtrn.extend((taila, bi) for bi in b)
          return rtrn
      

      这里的诀窍是使用迭代器,而不是可迭代对象。迭代器保持其状态。所以在 zip 之后,两个迭代器仍然应该指向 zip 停止的地方。 但是,如果 b 是较短的列表,这将不起作用。因为那时 zip 将从 a 中删除一个值并将其丢弃。你必须小心避免这种情况。 最简单的方法是只实现两个列表并明确处理长度差异。

      def merge(a, b):
          # ensure that we have lists, not anything else like iterators, sets, etc
          a, b = list(a), list(b)
          rtrn = list(zip(a, b))
          try:
              taila, tailb = rtrn[-1]
          except IndexError: # one or both empty
              return rtrn
          rtrnlen = len(rtrn)
          # only one of these loops will run, draining the longer input list
          # You could also use itertools.zip_longest for this
          rtrn.extend((ai, tailb) for ai in a[rtrnlen:])
          rtrn.extend((taila, bi) for bi in b[rtrnlen:])
          return rtrn
      

      【讨论】:

        【解决方案4】:

        我会使用zip_longest:

        from itertools import zip_longest
        
        def merge(a, b):
            return list(a and b and zip_longest(a, b, fillvalue=min(a, b, key=len)[-1]))
        

        同样的东西,不同的风格:

        def merge(a, b):
            if a and b:
                short = min(a, b, key=len)
                return list(zip_longest(a, b, fillvalue=short[-1]))
            return []
        

        【讨论】:

          【解决方案5】:
          from itertools import zip_longest
          
          def merge(a,b):
              if len(a) > len(b):
                  return list((zip_longest(a,b,fillvalue=b[-1])))
              else:
                  return list((zip_longest(a,b,fillvalue=a[-1])))`
          

          例如

           a = [2,3,5]
           b = [1,2]
           merge(a,b)
           [(2, 1), (3, 2), (5, 2)]
          

          zip_longest 文档链接

          https://docs.python.org/3/library/itertools.html#itertools.zip_longest

          【讨论】:

          • merge(a,b) 应该返回 [(2, 1), (3, 2), (5, 2)]
          • @newbie 我更正了该条件的代码
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-11-11
          • 1970-01-01
          • 2012-10-15
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多