2016-09-30 4 views
2

私はリスト内包を学習していますが、同じように動作するはずですが、変数を切り替えることで2つの異なる結果が得られます。リスト内包語のステートメントを並べ替えるときのNameError

[(i,j) for j in range(len(a[i])) for i in range(len(a))] 

戻り値:

[(0, 0), (1, 0), (2, 0), (3, 0), (4, 0), (0, 1), (1, 1), (2, 1), (3, 1), (4, 1), (0, 2), (1, 2), (2, 2), (3, 2), (4, 2), (0, 3), (1, 3), (2, 3), (3, 3), (4, 3), (0, 4), (1, 4), (2, 4), (3, 4), (4, 4)] 

予想通り

配列a[[0, 0, 0, 0, 0], [1, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]

リスト内包1つの作品に等しいです。

しかし、変数をひっくり返す... NameErrorで

[(j,i) for i in range(len(a[j])) for j in range(len(a))] 

結果:名「jが」

が定義されていない、私やjが最初に来るかどうかを重要なぜ誰かが私に説明していただけますか?

答えて

4

は、それはここで問題の変数の順序はありません。実際、List Comprehension 1を実行してもList Comprehension 2と同じ理由で動作しません。プログラム内でiを定義していたと推測しています。問題はforループの順序です。

例で説明しようとします。このように書くといいでしょう。

[ [(i,j) for j in range(len(a[i]))] for i in range(len(a))] 

私が追加した角括弧に注意してください。この場合、iを持つforループが最初に発生し、その後forループがjになります。ただし、これはタプルのリストのリストを返すことに注意してください。)代わりに、これも正常に動作します:

両方 forループが一緒にそのように(余分な括弧この時間)書かれている
[(i,j) for i in range(len(a)) for j in range(len(a[i]))] 

、彼らが読んだ左から右へ。

+0

最初の例であるネストされたリストのcompは、タプルのリストのリストを作成します。または、答えにその出力を含めてください。 –

+1

OKは意味があります。したがって、最初の例では、括弧の後のforループが最初に実行されますか?たとえば、ninecells = [[a [0] [0] + w、範囲(-1,2)のwの範囲(-1,2)のhの[0] [1] + h] 'それで'のためのhの範囲の 'は最初に走るでしょうか? – st4rgut

+0

@ PM2Ring良い点が追加されました。 – Meerness

6

forループを1つのリスト内で理解している場合は、同じ順序で同じループでforループを実行するのと同じです(forループ)。あなたが存在しない変数jlen(a[j])を行うときに

result = [(j,i) for i in range(len(a[j])) for j in range(len(a))] 

は、あなたがNameErrorことを得る理由である、あなたが見ることができるように

result = [] 
for i in range(len(a[j])): 
    for j in range(len(a)): 
     result.append((j, i)) 

と同等(ほぼ正確)です。

ご参考までに、最初のリストのコンプットもうまくいきません。あなたのコードでiを先に定義したと思うので、NameErrorが得られないのです。 aが行列である、つまりそのサブリストのすべてが同じ長さであり、少なくとも1つのサブリストが含まれていると仮定すると、そのリストのcompの少し改良されたバージョンがあります。

[(i,j) for j in range(len(a[0])) for i in range(len(a))] 

我々はまた、

[(j, i) for i in range(len(a)) for j in range(len(a[0]))] 

を行うことができ、それらのリストの両方がこのリストを作成カンプ:

[(0, 0), (1, 0), (2, 0), (3, 0), (4, 0), (0, 1), (1, 1), (2, 1), (3, 1), (4, 1), (0, 2), (1, 2), (2, 2), (3, 2), (4, 2), (0, 3), (1, 3), (2, 3), (3, 3), (4, 3), (0, 4), (1, 4), (2, 4), (3, 4), (4, 4)] 
+0

注:どちらもlistcompは機能しません。グローバルスコープまたはネストされたスコープが 'i'という名前の変数を定義していると思われます。また、' i'が法的インデックスである限り、マトリックスは 'nxn' (「範囲」の長さを計算するために)正しい順序ではないにもかかわらず機能します。 – ShadowRanger

+0

@ShadowRanger:はい、私は自分自身に気づきました。 :)私は私の答えでそれを言及するでしょう。 –

関連する問題