web-dev-qa-db-ja.com

2Dマトリックスのループのリスト内包置換

リストの内包表記を使用してforループを置き換えようとしています。

元のファイルは

_2 3 4 5 6 3
1 2 2 4 5 5
1 2 2 2 2 4
_

for loop

_line_number = 0
for line in file:
    line_data = line.split()
    Cordi[line_number, :5] = line_data 
    line_number += 1
_

出力は

_[[2 3 4 5 6 3]
 [1 2 2 4 5 5]
 [1 2 2 2 2 4]]
_

代わりにリスト内包表記を使用する場合、私が考えることができるのは(データ型をintに変更する必要があるため、プログラムの後半でプロットすることができます)

_Cordi1= [int(x) for x in line.split() for line in data]
_

しかし、出力は

_[1, 1, 1]
_

しかし、line.split() for line in dataは実際にはリストであり、試してみると

_Cordi1 = [int(x) for x in name of the list]
_

それは動作します、なぜこれが起こるのですか?

18
rankthefirst

ループの順序が入れ替わっています。それらは、左から右にネストするのと同じ方法で順序付けする必要があります。

_[int(x) for line in data for x in line.split()]
_

これは最初にdataをループし、次にlineの繰り返しごとにline.split()を繰り返してxを生成します。次に、これらから整数の1つのflatリストを作成します。

ただし、リストのリストを作成しようとしているため、リスト内包表記を別のリスト内にネストする必要があります。

_Cordi1 = [[int(i) for i in line.split()] for line in data]
_

デモ:

_>>> data = '''\
... 2 3 4 5 6 3
... 1 2 2 4 5 5
... 1 2 2 2 2 4
... '''.splitlines()
>>> [int(x) for line in data for x in line.split()]
[2, 3, 4, 5, 6, 3, 1, 2, 2, 4, 5, 5, 1, 2, 2, 2, 2, 4]
>>> [[int(i) for i in line.split()] for line in data]
[[2, 3, 4, 5, 6, 3], [1, 2, 2, 4, 5, 5], [1, 2, 2, 2, 2, 4]]
_

これから多次元のnumpy配列が必要な場合は、上記の配列を直接配列に変換するか、データから配列を作成してから再整形することができます。

_>>> import numpy as np
>>> np.array([[int(i) for i in line.split()] for line in data])
array([[2, 3, 4, 5, 6, 3],
       [1, 2, 2, 4, 5, 5],
       [1, 2, 2, 2, 2, 4]])
>>> np.array([int(i) for line in data for i in line.split()]).reshape((3, 6))
array([[2, 3, 4, 5, 6, 3],
       [1, 2, 2, 4, 5, 5],
       [1, 2, 2, 2, 2, 4]])
_
37
Martijn Pieters