Есть ли разница между `board[x, y]` и `board[x][y]` в Python?




arrays list (4)

Я работаю над учебником на веб-сайте 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)

Их код:

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) 

Может кто-нибудь объяснить мне, почему работает board[x,y] , и что именно происходит? Я никогда не видел этого раньше, кроме как для создания списков, и я не понимаю это концептуально.


В python [] это __getitem__ , который можно легко переписать.

И, 1, 2 в Python даст нам кортеж. да, нам не нужно () для создания непустого кортежа.

Таким образом, Numpy может сделать это очень легко, даже я могу.

In [1]: 1, 1
Out[1]: (1, 1)

In [2]: type(_)
Out[2]: tuple

In [3]: a = {(1, 1): 3}

In [4]: a[1, 1]
Out[4]: 3

In [5]: a[(1, 1)]
Out[5]: 3

In [6]: class NumpyArray(list):
   ...:     def __getitem__(self, index):
   ...:         if isinstance(index, tuple) and len(index) == 2:
   ...:             return self[index[0]][index[1]]
   ...:         return super().__getitem__(index)
   ...:

In [7]: b = NumpyArray([[0, 1], [2, 3]])

In [8]: b[1, 1]
Out[8]: 3

Вы можете использовать приведенный ниже код, чтобы попробовать свой собственный iPython.

class NumpyArray(list):
    def __getitem__(self, index):
        if isinstance(index, tuple) and len(index) == 2:
            return self[index[0]][index[1]]
        return super().__getitem__(index)

b = NumpyArray([[0, 1], [2, 3]])
b[1, 1]

На самом деле он не работает в базовом Python (как ваш пример). Если вы запускаете свой код, Python генерирует исключение: «TypeError: индексы списка должны быть целыми или кусочками, а не кортежем».

1, 1 передаваемый на board , интерпретируется как кортеж, и поскольку доска должна быть проиндексирована с целыми числами или срезами, это не будет работать.

Однако, если бы board представляла собой массив данных, подобный массиву, и разработчик реализовал поддержку индексации с кортежами, это бы сработало. Примером этого являются массивы в numpy .


Синтаксис board[x, y] вероятно, применяется к массиву-пустышке, который принимает этот синтаксис для реализации индексированных операций среза строк / столбцов. Посмотрите на эти примеры:

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

Конечно, запись my_list[x, y] выдает ошибку, потому что x, y на самом деле является кортежем (x, y) , и обычные списки не могут работать с кортежами в качестве значения индексации.


Это работает, потому что объект, который они используют (в данном случае массив 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])




indexing