【问题标题】:Summing lists using *args and a specified list index使用 *args 和指定的列表索引对列表求和
【发布时间】:2018-01-24 08:33:13
【问题描述】:

我之前在 Stack Overflow 上发布了一个问题,询问如何组合由整数值组成的列表,同时对各个索引处的值求和 (Summing lists of different lengths in Python beginning at a specified index using a function)。我从@pault 那里得到了很好的回答,但现在我想知道是否可以在函数中使用*args 来添加任意数量的列表。

例如,我可以有 4 个列表(或任意数量):

a = [0, 1, 2, 3, 4, 5, 6, 7]
b = [2, 4, 6, 8, 10, 12]
c = [1, 1, 1, 1, 1]
d = [2, 2, 2, 2, 2]

我想将列表bcd 插入到a 内的指定索引中。所以我可以说,在a[2] 插入列表b,在a[2] 插入ca[5] 插入d。结果将是[0 1 5 8 11 16 19 21]

这是我目前使用的代码(感谢@pault):

a = [0, 0, 0, 0, 0, 0, 0, 0, 0]
b = [1, 1, 1, 1, 1, 1, 1, 1, 1]
c = [5, 2]

def combine(lista, listb, index_in_list_a_to_start_insert):

    newb = [0]*index_in_list_a_to_start_insert + listb
    max_len = max(len(lista), len(newb))
    newa = lista if len(lista) >= max_len else lista + [0]*(max_len-len(lista))
    newb = newb if len(newb) >= max_len else newb + [0]*(max_len-len(newb))

    return [a + b for a, b in zip(newa,newb)][0:len(a)]

要点是将任意数量的列表添加到任意索引处的a,同时保持a 的长度相同,例如,如果我在a[6] 处添加列表b,结果将是[0, 1, 2, 3, 4, 5, 8, 11]。我认为我最大的问题是将列表与我希望插入的索引相关联,例如让列表b 进入a[3] 并指定列表c 进入a[4] 等,同时保持列表a 的长度相同,所以也许必须与**kwargs 进行一些配对?比如{'list': 'index'}?我真的不知道该怎么做。我正在使用 Python 3.4.3。

【问题讨论】:

    标签: python list function indexing


    【解决方案1】:

    如果我正确理解了您的问题,您实际上需要做的就是将listb 放入列表列表中。

    要对combine 进行最少的更改,请遍历listb 的每个项目以及使用zip 的每个索引,这两者现在都应该是列表列表:

    def combine(lista, listb, index_in_list_a_to_start_insert):
        if isinstance(listb[0], list):  # check if the first item in listb
                                        # is a list; check for empty lists
            for actual_list_b, actual_insert_index in zip(listb, index_in_list_a_to_start_insert):
                lista = combine(lista, actual_list_b, actual_insert_index)
            return lista
    
        newb = [0]*index_in_list_a_to_start_insert + listb
        max_len = max(len(lista), len(newb))
        newa = lista if len(lista) >= max_len else lista + [0]*(max_len-len(lista))
        newb = newb if len(newb) >= max_len else newb + [0]*(max_len-len(newb))
    
        return [a + b for a, b in zip(newa,newb)][0:len(a)]
    

    并使用上面的示例列表:

    >>> a = [0, 1, 2, 3, 4, 5, 6, 7]
    >>> b = [2, 4, 6, 8, 10, 12]
    >>> c = [1, 1, 1, 1, 1]
    >>> d = [2, 2, 2, 2, 2]
    >>>
    >>> combine(a, [b, c], [3, 4])
    [0, 1, 2, 5, 9, 12, 15, 18]
    >>>
    

    您需要为 listb 和索引列表添加更多 isinstance() 检查,以确保两者都是列表或都不是列表并且两者的长度相同,最短的一个确定 @ 的结果987654328@.

    【讨论】:

      【解决方案2】:

      我按照要求制作了这个功能。但是我没有使用*args,因为我只是认为它会使这个用例中的代码变得不那么清晰。在这里,我们有明确的命名,代码似乎按照您的要求进行。

      def combine(refList, listsToAdd, indexes):
          lenRef = len(refList)
      
          #   Navigating through lists you want to add.
          for listToAdd, startIndex in zip(listsToAdd, indexes):
              #   We'll need a break point later.
              lenToAdd = len(listToAdd)
      
              #   Setting index of the list to add numbers from.
              count = 0
      
              #   Going from the start index, until the end of our original list.
              for refIdx in range(startIndex, lenRef):
                  #   If we reach the end of our toAdd list... break.
                  if count >= lenToAdd:
                      break
                  refList[refIdx] += listToAdd[count]
                  count += 1
      
          return refList
      
      if __name__ == '__main__':
          a = [0, 1, 2, 3, 4, 5, 6, 7]
          b = [2, 4, 6, 8, 10, 12]
          c = [1, 1, 1, 1, 1]
          d = [2, 2, 2, 2, 2]
      
          newList = combine(a, listsToAdd=[b, c, d], indexes=[2, 2, 5])
          print newList
          # outputs : [0, 1, 5, 8, 11, 16, 19, 21]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-10-26
        • 1970-01-01
        • 2016-02-14
        • 2020-05-25
        • 2018-05-04
        • 1970-01-01
        • 2021-12-29
        • 1970-01-01
        相关资源
        最近更新 更多