Python中的`board [x,y]`和`board [x] [y]`之间有区别吗?

Bro*_*-AC 46 python arrays indexing numpy list

我正在研究GeekforGeeks网站上的教程,并注意到他们正在使用来检查数组中的点board[x,y],这是我从未见过的。我认为这行不通,但是当我运行程序时,一切都会按预期进行。

我尝试使用上面概述的方法和我更熟悉的方法(board[x][y])运行一个较小的代码示例,但是当我运行代码时,我得到了TypeError: list indices must be integers or slices, not tuple

我的代码:

board = [[1,1,1], [1,2,2], [1,2,2]]
win = 'True'

if board[1][1] == 2:
    win = 'True by normal standards'
    print(win)
if board[1, 1] == 2:
    win = 'True by weird standards'
    print(win)

print(win)
Run Code Online (Sandbox Code Playgroud)

他们的代码:

def row_win(board, player): 
    for x in range(len(board)): 
        win = True

        for y in range(len(board)): 
            if board[x, y] != player: 
                win = False
                continue

        if win == True: 
            return(win) 
    return(win) 
Run Code Online (Sandbox Code Playgroud)

有人可以向我解释为什么board[x,y]有效,究竟发生了什么?除了创建列表之外,我从未见过此内容,并且从概念上讲也没有掌握它。

U10*_*ard 43

他们能够做到这一点,因为他们正在使用NumPy,这不会对此造成任何错误。

>>> a = np.array([[1,1,1], [1,2,2], [1,2,2]])
>>> a[1,1]
2
>>> # equivalent to
>>> a = [[1,1,1], [1,2,2], [1,2,2]]
>>> a[1][1]
2
>>> 
Run Code Online (Sandbox Code Playgroud)

  • @lucidbrot:`a [1,1]`在numpy中表现更好,因为它避免了创建额外的numpy数组包装器;“ a [1] [1]”必须加载“ a”,索引为“ 1”,为该行创建一个包装器,然后在该行索引为“ 1”以获取单元格的值,然后清理该包装器。“ a [1,1]”直接加载单元格的值,而无需创建其他包装对象(如果索引不是恒定的,则必须按需创建“ tuple”,但是较小的“ tuple”字面量已在Python中进行了特殊优化,因此成本很小)。 (13认同)

Ant*_*Ant 10

之所以可行,是因为他们正在使用的对象(在本例中为numpy数组)使__getitem__方法过载。看这个玩具例子:

class MyArray:
  def __init__(self, arr):
    self.arr = arr
  def __getitem__(self, t):
    return self.arr[t[0]][t[1]]

myarr = MyArray([[1,1,1], [1,2,2], [1,2,2]])
print(myarr[0,1])
Run Code Online (Sandbox Code Playgroud)


Gri*_*mar 7

它实际上不适用于基本Python(如您的示例)。如果运行代码,Python会引发异常:'TypeError:列表索引必须是整数或切片,而不是元组'。

该1, 1传递给board被解释为一个元组,自董事会应当与整数或切片进行索引,这是不行的。

但是,如果board某种类型的类似数组的数据结构,并且开发人员已经实现了对元组索引的支持,那将是可行的。的一个示例是中的数组numpy。

  • 不要说*“它实际上不起作用。” *您的意思是*“如果`board`是列表列表*,则在基本Python中它实际上并不起作用。 (3认同)
  • 即使是最新的答案也错误地暗示了如果没有第三方库,这将无法工作,而显然可以做到:代码像`x = {}一样琐碎;x [1,1] = 42`可以正常工作。或者,更重要的是,没有什么禁止任何人使用很少的代码在基本Python中实现2D数组类的。 (2认同)

jfa*_*oni 5

该board[x, y]语法可能应用于 numpy 数组,该数组接受此语法以实现行/列索引切片操作。看看这些例子:

>>> x = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])  # creates 2D array
>>> x
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

>>> x[1]  # get second row (remember, index starts at 0)
array([4, 5, 6])

>>> x[:, 2]  # get third column
array([3, 6, 9])

>>> x[1, 2]  # get element on second row, third column
6

>>> x[1][2]  # same as before but with non-broadcasting syntax (i.e. works for lists as you are used to)
6

>>> x[1, 0:2]  # get first two elements of second row  
array([4, 5])

>>> x[0:2, 0:2]  # subsets the original array, "extracting" values from the first two columns/rows only
array([[1, 2],
       [4, 5]])
Run Code Online (Sandbox Code Playgroud)

当然,写入my_list[x, y]会抛出错误,因为x, y它实际上是一个 tuple (x, y),并且常规列表不能将 tuples 作为索引值。


smc*_*mci 5

因为它们board是numpy.ndarray包装它的任何一种或某种类型,例如pandas.DataFrame board[x,y]是熊猫 2D 索引,而不是基础 Python。

你应该做的type(board)。或者向我们展示创建和初始化的行board。

此外,当您说“当我运行程序时,一切都按预期进行”时,您应该以交互模式 ( python -i) 运行,然后您可以运行类似的查询type(board)(或在 iPython/jupyter 类型whos中查看变量及其类型的列表)