質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

577閲覧

Python3 二次元リストの表示

Alter_9524

総合スコア22

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2018/10/22 08:16

Pythonで二次元リストを出力するときなんですが

[出力] [[0,1,2], [10,11,12], [20,21,22]]

このように3×3の二次元リストに、行を一つ下に行くごとに10ずつ増えていくように出力させたいと思っています。

[試したコード] #3×3のリストを生成 list = [[0]*3]*3 for i in range(3): for j in range(3): list[i][j] = j +(10 * i) print(list)
[得られた出力] [[20, 21, 22], [20, 21, 22], [20, 21, 22]]

どういうわけかすべての行が同じになってしまいます。
一体どうコードを書き直せばよいでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

Python初心者が必ずと言って良いほど嵌る罠です。

Python

1>>> inner = [0] * 3 2>>> inner 3[0, 0, 0] 4>>> 5>>> outer = [inner] * 3 6>>> outer 7[[0, 0, 0], [0, 0, 0], [0, 0, 0]] 8>>> 9>>> inner[0] = 1 10>>> outer 11[[1, 0, 0], [1, 0, 0], [1, 0, 0]]

結論から言えば、次のように内包表記を使ってリストを生成してください。

Python

1>>> lst = [[0 for _ in range(3)] for _ in range(3)] 2>>> lst 3[[0, 0, 0], [0, 0, 0], [0, 0, 0]] 4>>> 5>>> lst[0][0] = 1 6>>> lst 7[[1, 0, 0], [0, 0, 0], [0, 0, 0]]

実際にはリストの乗算で足りる部分もありますが、初心者のうちはなかなか見分けが付かないかと。
定型文だと思ってリスト内包を使うのが吉です。

原因

多く記事が書かれるネタですので、適当にリンクを貼って済ませてしまいます。

ついでに

変数にlistと言う名前を付けるのは避けてください。
解決しづらいエラーを引き起こします。

Python

1>>> list('spam') 2['s', 'p', 'a', 'm'] 3>>> 4>>> list = [1, 2, 3] 5>>> 6>>> list('spam') 7Traceback (most recent call last): 8 File "<stdin>", line 1, in <module> 9TypeError: 'list' object is not callable

同様に str sum id max dict next なども使ってしまいがちです。

投稿2018/10/22 08:21

編集2018/10/22 08:26
LouiS0616

総合スコア35660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Alter_9524

2018/10/22 08:38

[[0]*3]*3でリストを生成すると各行のIDが同一のものになってしまうんですね。 つまり最終的に代入された[20,21,22]がすべての行に代入されてしまった.... ありがとうございます。大変勉強になりました!
Alter_9524

2018/10/22 08:43

確かに文字列を配列に格納するlist()メソッドと混同してしまう可能性がありますね。 そちらも気をつけるようにします。
guest

0

大きく2つの方法でかいてみました。
まずは すべて 0 の 2 次元配列を作ってから、 値を設定していきます。

pythone

1# NG: list = [[0] * 3] * 3] 2 3# lit = [[0] * 3, [0] * 3, [0] *3] 4 5# lst = [] 6# for i in range(3): 7# lst.append([0] * 3) 8 9# lst = [[0 for x in range(3)] for y in range(3)] 10 11lst = [[0] * 3 for y in range(3)] 12 13for i in range(3): 14 for j in range(3): 15 lst[i][j] = j + (10 * i) 16print(lst)

すべて 0 の 2 次元配列の作り方は, コメントにしてある別の方法でも OK です。
ただし list = [[0] * 3] * 3] は NG です。
これが質問文にあった方法です。これが NG bな理由は以下を参照してください。

参考情報

  • Pythonで2次元配列の静的確保と動的確保

http://sonickun.hatenablog.com/entry/2014/06/13/132821

  • 2次元配列(リストのリスト)を初期化する際の注意

https://note.nkmk.me/python-list-initialize/

  • 2次元リスト(配列)

https://snakify.org/ja/lessons/two_dimensional_lists_arrays/

次に、直接 要素の値を設定しながら2次元配列を作っていく方法です。

python3

1lst = [list(map(lambda x: x + 10 * y, [x for x in range(3)])) for y in range(3)] 2print(lst)

これは、 まず [0, 1, 2] を作ります。([x for x in range(3)]) の部分)
それに対して 各要素 に 10 を足したもの、 20 を足したもの、 30 を足したもの
をつくっていっています。 [list(map(lambda x: x + 10 * y, [0, 1, 2])]の部分)

どちらの方法も実行すると

[[0, 1, 2], [10, 11, 12], [20, 21, 22]]

が表示されます。

投稿2018/10/22 14:04

katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問