【问题标题】:Assign value to an individual cell in a two dimensional python array [duplicate]为二维python数组中的单个单元格赋值[重复]
【发布时间】:2012-03-16 14:10:27
【问题描述】:

假设我在 Python 中有以下空二维数组:

q = [[None]*5]*4

我想将5 的值分配给q 的第一列中的第一行。本能地,我做了以下事情:

q[0][0] = 5

但是,这会产生:

 [[5, None, None, None, None], 
  [5, None, None, None, None], 
  [5, None, None, None, None], 
  [5, None, None, None, None]]

每个数组的第一个元素被初始化为5,我认为只有第一个数组的第一个元素会得到更新。我有两个问题:

  1. 为什么 Python 会初始化每个数组的第一个值,而不仅仅是第一个?
  2. 有没有更好的方法来完成我想做的事情?

【问题讨论】:

  • 同样的问题,完全忘了使用对象的引用

标签: python arrays list


【解决方案1】:

这并没有达到你的预期。

q = [[None]*5]*4

它多次重用list 对象。正如您在对重复使用的列表对象中的一个单元格进行更改时看到的那样。

一个值为[None]的列表被使用了五次。

一个值为[[None]*5] 的列表被使用了四次。

q = [ [ None for i in range(5) ] for j in range(4) ]

可能是您正在寻找的更多内容。

这明确避免重复使用列表对象。

80% 的情况下,您真正​​想要的是一本字典。

q = {}
q[0,0]= 5

也可以。您不会从 None 值的预定义网格开始。但一开始就很少需要它们。

在 Python 2.7 及更高版本中,您可以这样做。

q = { (i,j):0 for i in range(5) for j in range(4) }

这将构建一个由 2 元组索引的网格。

{(0, 1): 0, (1, 2): 0, (3, 2): 0, (0, 0): 0, (3, 3): 0, (3, 0): 0, (3, 1): 0, (2, 1): 0, (0, 2): 0, (2, 0): 0, (1, 3): 0, (2, 3): 0, (4, 3): 0, (2, 2): 0, (1, 0): 0, (4, 2): 0, (0, 3): 0, (4, 1): 0, (1, 1): 0, (4, 0): 0}

【讨论】:

  • 如果你分享导致 80% 价值的研究,我会给你 +1。
  • 这是帕累托原理。 en.wikipedia.org/wiki/Pareto_principle。 80% 的时间,您只需要 20% 的数据结构。
  • 原始类型并非完全如此。外部“4”创建了 4 个指向同一个列表的引用,但内部“5”没有创建 5 个指向相同“None”的引用。所以你仍然可以 [[None] * 5 for j in range(4)]
  • @qkhhly:不,它对所有类型的行为完全相同。您可以通过查看 [[id(x) for x in sublist] for sublist in q] 来确认所有引用都指向相同的 None。
  • 使用列表理解 [[x for x in mylist] for x in range(9)] 在列表列表的情况下对我没有帮助。改用[[x for x in copy.deepcopy(mylist)] for x in range(9)] 解决了这个问题。
【解决方案2】:

为什么你有这个列表,只是重复了四次!每次您执行*4 时,Python 都不会重新生成该列表。它使用相同的列表对象。

要解决这个问题,您需要强制 python 每次都为您重新生成该列表:

[ [None] * 5 for i1 in range(4) ]

在这种情况下,我使用的是列表推导。

【讨论】:

    【解决方案3】:
    q = [[None]*5]*4
    print(q)
    q[1][1]=4
    print(q)
    q = [ [ None for i in range(5) ] for j in range(4) ]
    q[1][1]=4
    print(q)
    

    结果:

    [[None, None, None, None, None], [None, None, None, None, None], [None, None, None, None, None], [None, None, None, None, None]]
    [[None, 4, None, None, None], [None, 4, None, None, None], [None, 4, None, None, None], [None, 4, None, None, None]]
    [[None, None, None, None, None], [None, 4, None, None, None], [None, None, None, None, None], [None, None, None, None, None]]
    

    【讨论】:

      【解决方案4】:

      为什么 Python 会初始化每个数组的第一个值,而不仅仅是第一个?

      因为它们是同一个数组,被多次引用。

      有没有更好的方法来完成我想做的事情?

      创建结构,使外部数组引用单独的内部数组,而不是重复使用一个。其他答案提供了这样做的方法。

      【讨论】:

        【解决方案5】:

        答案很简单,永远不要使用

        q = [[None]*5]*4
        

        当你做作业时

        q[0][1]=5 多次为 1 列的多行赋值 尝试打印(q)

        相当使用

        q = { (i,j):0 for i in range(5) for j in range(4) }
        

        那么q[0][1]=5将只分配一次 试试

        print(q)
        

        【讨论】:

          【解决方案6】:

          第二个问题的答案: 使用 numpy 是一种选择。请参阅以下代码。

          import numpy as np
          
          # creating 2D array with nans
          num_of_rows = 5
          num_of_cols = 3
          a = np.full((num_of_rows, num_of_cols), np.nan) 
          #for zero vals: a = np.zeros((num_of_rows, num_of_cols))
          
          # placing number 5 in row 3, col 1
          value = [5]
          position_row = 3
          position_col = 1
          # the put command below flattens the 2D array
          position = [int(num_of_cols * position_row + position_col)] 
          np.put(a, position, value)
          

          结果:

          [[ nan  nan  nan]
           [ nan  nan  nan]
           [ nan  nan  nan]
           [ nan   5.  nan]
           [ nan  nan  nan]]
          

          【讨论】:

            【解决方案7】:

            如果您想使用列表而不是其他人建议的字典,则可以使用:

            q[0] = [5,None,None,None,None]
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2021-12-31
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-12-17
              相关资源
              最近更新 更多