¿Hay alguna diferencia entre `tablero[x, y]` y `tablero[x][y]` en Python?
arrays list (6)
Estoy trabajando en un
tutorial en el sitio web de GeekforGeeks
y noté que están revisando un punto en una matriz usando la
board[x,y]
, que nunca había visto antes.
No creo que esto funcione, pero cuando ejecuto el programa, todo sale como se esperaba.
Intenté ejecutar un ejemplo de código más pequeño usando su método descrito anteriormente en comparación con el método con el que estoy más familiarizado (
board[x][y]
), pero cuando ejecuto mi código, obtengo
TypeError: list indices must be integers or slices, not tuple
Mi código:
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)
Su código:
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)
¿Alguien puede explicarme por qué funciona el
board[x,y]
y qué está sucediendo exactamente?
Nunca he visto esto antes, excepto para crear listas, y no lo entiendo conceptualmente.
En python,
[]
es
__getitem__
, que puede reescribirse fácilmente.
Y,
1, 2
en python nos dará una tupla.
sí, realmente no necesitamos
()
para crear una tupla no vacía.
Entonces, Numpy puede hacer esto muy fácilmente, incluso yo puedo.
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
Puede usar el siguiente código para probar en su propio 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]
En realidad, no funciona en Python base (como su ejemplo). Si ejecuta su código, Python lanza una excepción: ''TypeError: los índices de la lista deben ser enteros o sectores, no tuplas''.
El
1, 1
pasado al
board
se interpreta como una tupla y dado que el tablero debe indexarse con enteros o rebanadas, esto no funcionará.
Sin embargo, si la
board
fuera algún tipo de estructura de datos tipo matriz y el desarrollador hubiera implementado soporte para indexar con tuplas, esto funcionaría.
Un ejemplo de esto son las matrices en
numpy
.
Eso funciona porque el objeto que están utilizando (en este caso, una matriz numpy) sobrecarga el método
__getitem__
.
Ver este ejemplo de juguete:
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])
La sintaxis de la
board[x, y]
probablemente se esté aplicando a una matriz numpy, que acepta esta sintaxis para implementar operaciones de corte indexadas de fila / columna.
Eche un vistazo a estos ejemplos:
>>> 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]])
Por supuesto, escribir
my_list[x, y]
arroja un error porque
x, y
es en realidad una tupla
(x, y)
, y las listas normales no pueden funcionar con tuplas como un valor de indexación.
Pueden hacerlo, ya que están usando NumPy, lo que no arrojará un error al respecto.
>>> 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
>>>
Debido a que su
board
es
numpy.ndarray
o algún tipo que lo envuelve, por ejemplo,
pandas.DataFrame
Debiste haber hecho
type(board)
.
O muéstrenos las líneas que crean e inicializan el
board
.
Además, cuando dices "cuando ejecuto el programa, todo sale como se esperaba", debes ejecutarlo en modo interactivo (
python -i
), luego puedes ejecutar consultas como
type(board)