【问题标题】:How to create a multi-dimensional list如何创建多维列表
【发布时间】:2013-07-14 04:40:35
【问题描述】:

我想初始化一个多维列表。基本上,我想要一个 10x10 的网格 - 一个包含 10 个列表的列表,每个列表包含 10 个项目。

每个列表值都应该初始化为整数 0。

在单行中执行此操作的明显方法:myList = [[0]*10]*10 不起作用,因为它会生成一个包含 10 个对一个列表的引用的列表,因此更改任何行中的项目会更改所有行中的项目。

我看到的文档谈到了使用[:] 来复制列表,但是在使用乘数时仍然不起作用:myList = [0]*10; myList = myList[:]*10myList = [[0]*10]*10 具有相同的效果。

没有创建myList.append()s的循环,有没有一种快速有效的方法来以这种方式初始化列表?

【问题讨论】:

  • 我认为[:] 的想法也可以,例如[x[:] for x in [[0]*10]*10].
  • 请参阅 this question 以了解为什么 [[0]*10]*10 无法按预期工作。

标签: python list


【解决方案1】:

您可以使用list comprehension 非常有效地做到这一点:

a = [[0] * number_cols for i in range(number_rows)]

【讨论】:

  • 很好,避免了显而易见的答案所具有的嵌套 for 循环,但仅当您希望数组初始化的值可以被多次引用时才有效,所以如果您希望填充数组则不行具有类的唯一实例。
  • 请注意,现在可以使用类似数组的语法访问数据:a[col_num][row_num]
  • 我没有做出改变。现在刚刚编辑,因为这是表示矩阵的更自然的方式。
  • @Alex,你是对的。外部列表首先被索引。
【解决方案2】:

这是为...嵌套的list comprehension 的工作!

[[0 for i in range(10)] for j in range(10)]

【讨论】:

  • 我相信这更清楚,并且通常优于替代方案(例如使用[0]*10)。
  • 如果列表元素是可变对象,这是正确的解决方案。
  • 1000X1000 所用时间为 0.00521 秒
【解决方案3】:

只是想我会添加一个答案,因为该问题要求一般 n 维情况,我认为尚未回答。您可以使用以下示例对任意数量的维度递归地执行此操作:

n_dims = [3, 4, 5]

empty_list = 0
for n in n_dims:
    empty_list = [empty_list] * n

>>>empty_list
>>>[[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]],
   [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]],
   [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]],
   [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]],
   [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]]

【讨论】:

  • 这与问题中描述的问题相同 - 它创建了对同一列表的许多引用。
【解决方案4】:

您实际上可能需要array 而不是一些列表。几乎每次我看到这种“预先调整大小的嵌套列表”模式时,都会觉得有些地方不太对劲。

【讨论】:

    【解决方案5】:

    另一个解决方案是使用 NumPy 库:

    import numpy as np
    
    zero_array = np.zeros((10, 10), dtype='int')
    

    如有必要,可以使用.tolist() 方法轻松地将其转换为常规 python 列表。

    【讨论】:

      【解决方案6】:

      我发现要得到你的意思,你需要你自己

      import copy
      
      def n_dim_list(dims, init_val):
          if not dims:
              return []
          lst = [init_val for i in range(dims[-1])]
          for d in dims[::-1][1::]:
              lst = [copy.deepcopy(lst) for i in range(d)]
      return lst
      

      其中 dims 是您想要的维度数量的长度列表,内容是每个维度中所需 nd-list 的大小。 不是最优雅但清晰且能胜任的工作。

      【讨论】:

        【解决方案7】:

        另一种方法,但使用 OP's 拒绝的方法。

        import numpy as np
        myList = [[0]*10]*10
        myList = np.array(myList)
        l=myList.tolist()
        myList=l
        

        下面的输出和测试:

        >>> l
        [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
        >>> l[0][0]=100
        >>> l
        [[100, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
        

        输出与l[0] 的预期克隆不同。

        虽然这不是时间效率。一个 1000X1000 的列表需要将近 7 秒,而列表解析只需要 0.0052158 秒。

        【讨论】:

          【解决方案8】:

          这是一个使用递归列表推导适用于任意数量维度的函数。它不需要任何导入即可工作。

          def init_list(dims, val):
              if len(dims) == 0:
                  raise ValueError("Requires at least 1 dimension.")
          
              if len(dims) == 1:
                  return [val for _ in range(dims[0])]
          
              return [init_list(dims[1:], val=val) for _ in range(dims[0])]
          

          例子:

          >>> init_list([3, 2, 1], val=0)
          [[[0], [0]], [[0], [0]], [[0], [0]]]
          

          【讨论】:

            【解决方案9】:

            两种常见且简短的方法:

            第一:

            [[0] * n] * m
            

            第二:

            [[0 for column in range(n)] for row in range(m)]
            

            【讨论】:

              猜你喜欢
              • 2017-02-19
              • 1970-01-01
              • 2011-12-14
              • 2012-11-07
              • 2013-03-12
              • 2023-03-23
              • 2011-04-18
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多