web-dev-qa-db-ja.com

Pythonの `board [x、y]`と `board [x] [y]`の間に違いはありますか?

私は GeekforGeeks Webサイトのチュートリアル で作業しており、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]が機能する理由と、正確には何が起こっているのかを私に説明できますか?リストを作成する以外は、これまで見たことがないので、概念的には把握していません。

46
Broski-AC

彼らは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
>>> 
44
U10-Forward

彼らが使用しているオブジェクト(この場合は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])
11
Ant

これは実際にはbase Python=(例のように)では機能しません。コードを実行すると、Pythonが例外をスローします: 'TypeError:リストインデックスはタプルではなく整数またはスライス。

1, 1に渡されたboardはタプルとして解釈され、ボードには整数またはスライスでインデックスを付ける必要があるため、これは機能しません。

ただし、boardが何らかのタイプの配列のようなデータ構造であり、開発者がタプルを使用したインデックス付けのサポートを実装している場合、これは機能します。この例は、numpyの配列です。

8
Grismar

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

もちろん、my_list[x, y]は、x, yは実際にはタプル(x, y)、そして通常のリストはタプルをインデックス値として使用できません。

5
jfaccioni

それらのboardは_numpy.ndarray_またはそれをラップする何らかの型であるため、たとえば_pandas.DataFrame_ _board[x,y]_ is pandas =ベースPythonではなく、2Dインデックス。

type(board)を実行する必要があります。または、boardを作成して初期化する行を示します。

また、「プログラムを実行すると、すべてが期待どおりに進む」と言う場合は、インタラクティブモード(_python -i_)で実行する必要があります。その後、type(board)(またはiPython/jupyter type whos変数とそのタイプのリストを表示します)

5
smci

Pythonでは、[]__getitem__、これは簡単に書き換えることができます。

そして、1, 2 in 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]
2
LiuXiMin