【问题标题】:Multiply every element in a nested list by a constant将嵌套列表中的每个元素乘以一个常数
【发布时间】:2019-06-19 02:40:25
【问题描述】:

我已经阅读了很多类似的帖子hereherehere 等等,但我无法解决我的问题。我有一个这样的配对列表:

 my_list = [[[0, 3], [0, 0]], [[77, 94], [76, 94], [77, 93], [76, 93], [76, 90], [77, 84], [76, 88]], [[25, 31], [10, 0]]]

我想将每个整数乘以-1。我尝试了不同的事情并得到了不同的错误,但这是我认为最合乎逻辑的代码:

for p in range(len(my_list):
    for q in range(len(mylist[p])):
        my_new_list = [[i,j] * -1 for [i,j] in my_list[p][q]]

而这个甚至不工作!我最终想要的是这样的:

my_new_list = [[[0, -3], [0, 0]], [[-77, -94], [-76, -94], [-77, -93], [-76, -93], [-76, -90], [-77, -84], [-76, -88]], [[-25, -31], [-10, 0]]]

有人可以帮我解决这个问题吗?

【问题讨论】:

    标签: python list


    【解决方案1】:

    您的问题是 您的最内层循环正在创建一个新的子列表,但没有将其适当地分配回(新列表或 my_list)。 上一次迭代的结果是重新- 每次都写。

    你需要的是一个包含三个循环的列表推导式,每个循环一个循环:

    my_new_list = [[[z * -1 for z in y] for y in x] for x in my_list]
    

    如果你能保证你的最里面的列表总是成对的,你可以按照@ShadowRanger 的建议简化它,并使用带有两个循环的嵌套列表组合,

    my_new_list = [[[-a, -b] for a, b in x] for x in my_list]
    

    这相当于做

    import copy 
    
    my_new_list = copy.deepcopy(my_list)
    for x in my_new_list:
        for y in x:
            for i, z in enumerate(y): 
                y[i] = z * -1   # notice the assignment back to the sublist
    

    【讨论】:

    • 鉴于最里面的lists 似乎总是成对的,而不是任意长度,可能需要通过将其简化为:[[[-a, -b] for a, b in x] for x in my_list] 来简化/加速,保存最里面的list理解支持在 list 文字中内联相同的工作。请注意,对于普通数字,-a 只是拼写a * -1 的一种更短/更快的方式,所以为了简洁起见,我使用了一元减号。
    • @ShadowRanger 感谢您的提示,这是对配对的有用优化。
    【解决方案2】:

    要对任意深度的列表执行此操作,您可以使用以下递归函数:

    def negate(list_or_int):
        if isinstance(list_or_int, list):
            # It's a list, so call negate on every element
            return [negate(i) for i in list_or_int]
    
        # It's an int, so just return the negative
        return -list_or_int
    
    my_new_list = negate(my_list)
    

    【讨论】:

      【解决方案3】:

      通过递归生成器可以实现更高效、更优雅的解决方案:

      def kprod(k,itr):
          for x in itr:
              yield k*x if isinstance(x, (int, float)) else tuple(kprod(k,x))
      

      如果需要,请将 tuple 替换为 list,但请注意元组会稍微快一些。

      该函数适用于任何深度和类型的嵌套迭代并返回一个生成器,因此当您想要显示其内容时,您必须通过对其应用tuplelist 来扩展它:

      >>> my_list = [[[0, 3], [0, 0]], [[77, 94], [76, 94], [77, 93], [76, 93], [76, 90], [77, 84], [76, 88]], [[25, 31], [10, 0]]]
      >>> tuple(kprod(-1,my_list))
      (((0, -3), (0, 0)), ((-77, -94), (-76, -94), (-77, -93), (-76, -93), (-76, -90), (-77, -84), (-76, -88)), ((-25, -31), (-10, 0)))
      
      >>> tuple(kprod(2,[3]))
      (6,)
      
      >>> tuple(kprod(2,[4,(5,(-1,0)),6]))
      (8, (10, (-2, 0)), 12)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-05-23
        • 1970-01-01
        • 2016-05-12
        • 2023-03-19
        • 1970-01-01
        • 1970-01-01
        • 2015-08-15
        • 1970-01-01
        相关资源
        最近更新 更多