web-dev-qa-db-ja.com

配列を反復処理する

私はブールの配列を持っています、そして今、私はそれらのエントリーを数字に交換したいと思います。

False => 0
True => 1

2つの異なるコードを記述しましたが、どちらが優れているのか、なぜなのかを知りたいと思います。これは実際に問題を解決することではなく、学習することについてです。

arr = [[True,False],[False,True],[True,True]]

for i,row in enumerate(arr):
    for j,entry in enumerate(row):
        if entry:
            arr[i][j] = 1
        else:
            arr[i][j] = 0
print(arr)

2番目のアプローチ:

arr = [[True,False],[False,True],[True,True]]

for i in range(len(arr)):
    for j in range(len(arr[i])):
        if arr[i][j]:
            arr[i][j] = 1
        else:
            arr[i][j] = 0    
print(arr)

itertoolsなどをインポートしてこれを行う方法があることを読みました。 「オンボードツール」を使用して処理できる場合は、物をインポートすることはあまり好きではありませんが、この問題に使用する必要がありますか?

8
Swift

配列を定義しましょう:

>>> arr = [[True,False],[False,True],[True,True]]

それでは、ブール値を整数に変換しましょう。

>>> [[int(i) for i in row] for row in arr]
[[1, 0], [0, 1], [1, 1]]

代わりに、置換されるものについてより柔軟にしたい場合は、三項ステートメントを使用できます。

>>> [[1 if i else 0 for i in row] for row in arr]
[[1, 0], [0, 1], [1, 1]]
12
John1024

Forループを使用したい場合(たとえば、新しい配列を作成するのではなく、既存の配列を変更したい場合)、コードを単純化する必要があります。

最初に、インデックス付けを削除して外側のループを単純化します(ネストされた配列よりも行を変更する方が簡単なので、その必要はありません)。

_for row in arr:
    for j, entry in enumerate(row):
        if entry:
            row[j] = 1
        else:
            row[j] = 0
_

これらの種類の単純なifステートメントは、if式を使用することで単純化できます。

_ row[j] = 1 if entry else 0
_

ただし、この場合はさらに改善できます。 boolintのサブクラス(つまり、すべてのboolintである)、およびTrueFalseはそれぞれ正確に_1_および_0_と定義されています-PEP 285の仕様セクションまでスクロールダウンした場合( https://www.python.org/dev/peps/pep- 0285 / )その等価性は偶然ではなく、設計上非常に多いことがわかります。

したがって、int(True) == 1およびint(False) == 0であるため、基になる整数値[*]を取得するためにintコンストラクターを使用できます。if式は次のように簡略化できます。

_row[j] = int(entry)
_

[*]技術的には、これは基本クラスへの明示的なアップキャストであり、変換コンストラクターではありません。

簡略化されたコード:

_for row in arr:
    for j, entry in enumerate(row):
        row[j] = int(entry)
_
4
thebjorn