【问题标题】:How to number a 2 dimensional list?如何给二维列表编号?
【发布时间】:2019-07-21 20:38:41
【问题描述】:

我将这些列表包含在我要编号的列表中。我还有两个变量,行和列,它们被作为输入。

lst = row*[column*[0]]

这使得列表中的列表用零填充,所以如果行 = 6 和列 = 10,它看起来像:

[[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]] 

我怎样才能改变它,使它看起来像这样:

[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],   
[11, 12, 13, 14, 15, 16, 17, 18, 19, 20],     
[21, 22, 23, 24, 25, 26, 27, 28, 29, 30],    
[31, 32, 33, 34, 35, 36, 37, 38, 39, 40],     
[41, 42, 43, 44, 45, 46, 47, 48, 49, 50],     
[51, 52, 53, 54, 55, 56, 57, 58, 59, 60]]

谢谢!

【问题讨论】:

    标签: python arrays list


    【解决方案1】:

    我认为这将是最“pythonic”的方式:

    from pprint import pprint
    
    rows = 6
    cols = 10
    
    lst = [[(j*cols+i) for i in range(1,cols+1)] for j in range(rows)]
    
    pprint(lst)
    

    输出:

    [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
     [11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
     [21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
     [31, 32, 33, 34, 35, 36, 37, 38, 39, 40],
     [41, 42, 43, 44, 45, 46, 47, 48, 49, 50],
     [51, 52, 53, 54, 55, 56, 57, 58, 59, 60]]
    

    【讨论】:

    • 比没有嵌套嵌套 for 循环的更 Python 吗?
    • @fountainhead:是的——虽然可以说不像你的那样“直观”,但它仍然非常高效和可读。
    【解决方案2】:

    快速而肮脏的解决方案是:

    lst = []
    for r in range(row):
        lst.append([])
        for c in range(column):
            lst[r].append(c + r * column)
    

    这可以使用 numpy 和 reshaping 更简洁地实现,例如:

    lst = numpy.arange(row * column).reshape(row, column).tolist()
    

    【讨论】:

      【解决方案3】:

      试试这个:

      l = []
      for i in range(0, 6):
          row = []
          for j in range(1,11):
              row.append(i*10+j)
          l.append(row)
      l
      >>>[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
         [11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
         [21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
         [31, 32, 33, 34, 35, 36, 37, 38, 39, 40],
         [41, 42, 43, 44, 45, 46, 47, 48, 49, 50],
         [51, 52, 53, 54, 55, 56, 57, 58, 59, 60]]
      

      【讨论】:

        【解决方案4】:

        您可以使用ziprange 获取此信息。

        list(zip(*[iter(range(1, row*column+1))]*column))
        

        这会产生一个元组列表,但如果您需要一个列表列表,只需 map listzip

        list(map(list, zip(*[iter(range(1, row*column+1))]*column)))
        

        结果:

        [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [10, 11, 12, 13, 14, 15, 16, 17, 18, 19], [20, 21, 22, 23, 24, 25, 26, 27, 28, 29], [30, 31, 32, 33, 34, 35, 36, 37, 38, 39], [40, 41, 42, 43, 44, 45, 46, 47, 48, 49], [50, 51, 52, 53, 54, 55, 56, 57, 58, 59]]

        【讨论】:

        • 相当奇怪的方法,但仍然很有趣。
        • this 回答我自己的一个问题非常有用,有时可以非常漂亮地进行修改。这就是我在这里所做的一切
        • @AlexanderReynolds 这不仅是一种有趣/怪诞的方法,而且比 list comp 替代方法快约 5 倍。见repl.it/repls/GracefulThirdOpensource
        • 那个比较是错误的,每个产生完全不同的输出(虽然更正后的列表 comp 仍然较慢)
        • 我刚刚意识到,为什么你的答案没有产生 OP 想要的结果,哎呀不是你的答案
        【解决方案5】:

        我会考虑解决此问题的方式是认识到您正在生成列表列表,而不是二维数组。

        另外,鉴于您的经验水平,我认为程序方法可能是您的一个良好开端。

        # Your given information
        row = 6
        col = 10
        
        # Initialize an empty list of lists
        lst = []
        
        # Continuously append lists by converting range() objects
        i = 1
        while i <= (row * col):
          next_i = i + col
          arr.append(list(range(i, next_i)))
          i = i + next_i
        

        接下来的一些好的步骤是调查range()list() 的文档。乍一看,它们看起来像函数,但实际上它们是不可变的和可变的(分别)sequence type

        注意:对您的问题的评论说

        您碰巧创建了一个列表,其中包含一堆对同一个内部列表的引用

        为了说明这一点,请观察当我尝试修改(变异)列表列表中的一个元素时 python 交互式解释器中发生的情况:

        >>> row = 6
        >>> column = 10
        >>> lst = row*[column*[0]]
        >>> lst
        [[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]]
        >>> lst[0][0] = 999 # set just row 0, column 0 to 999
        >>> lst
        [[999, 0, 0, 0, 0, 0, 0, 0, 0, 0], [999, 0, 0, 0, 0, 0, 0, 0, 0, 0], [999, 0, 0, 0, 0, 0, 0, 0, 0, 0], [999, 0, 0, 0, 0, 0, 0, 0, 0, 0], [999, 0, 0, 0, 0, 0, 0, 0, 0, 0], [999, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
        

        结果是每一行的第一列都变成了999。这是因为当你将[column*[0]]创建的list乘以row时,实际上是什么发生的事情是你有相同的listrow 实例。因此,当您提及其中之一时,您会以这种方式提及所有这些。小心这种“列表乘法”。

        【讨论】:

          【解决方案6】:

          为什么不使用列表推导如下:

          lst = [[(i+j*column)+1 for i in range(column)] for j in range(row)]
          

          【讨论】:

          • 您的行和列倒置了,请参阅下面的 martineau 的答案。
          【解决方案7】:

          这也有效:

          lst = [list(range(1+i*column, 1+(i+1)*column)) for i in range(row)]
          

          输出:

          print (lst)
          [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [11, 12, 13, 14, 15, 16, 17, 18, 19, 20], [21, 22, 23, 24, 25, 26, 27, 28, 29, 30], [31, 32, 33, 34, 35, 36, 37, 38, 39, 40], [41, 42, 43, 44, 45, 46, 47, 48, 49, 50], [51, 52, 53, 54, 55, 56, 57, 58, 59, 60]]
          

          说明:

          1. 我们正在构建一个外部列表,其中每个元素都是int 的(内部)列表。
          2. 列表推导构建外部列表。
          3. for 循环之前的表达式,即list(range(1+i*column, 1+(i+1)*column)),表示此外部列表的每个元素。这个元素是int 的列表,首先使用range(1+i*column, 1+(i+1)*column) 构造为范围对象。然后将 this 返回的范围对象传递给 list() 以将其转换为列表。

          请注意,表达式range(1+i*column, 1+(i+1)*column)直观的,因为它反映了在i 第行中,值将“范围”从(1+i*column) to 1+(i+1)*column。例如,在 6x10 的情况下,当i = 2 时,对应行的值将“范围”从1+2*101+(2+1)*10

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2021-04-20
            • 1970-01-01
            • 1970-01-01
            • 2013-03-12
            • 1970-01-01
            • 1970-01-01
            • 2021-03-30
            相关资源
            最近更新 更多