検索ガイド -Search Guide-

単語と単語を空白で区切ることで AND 検索になります。
例: python デコレータ ('python' と 'デコレータ' 両方を含む記事を検索します)
単語の前に '-' を付けることで NOT 検索になります。
例: python -デコレータ ('python' は含むが 'デコレータ' は含まない記事を検索します)
" (ダブルクオート) で語句を囲むことで 完全一致検索になります。
例: "python data" 実装 ('python data' と '実装' 両方を含む記事を検索します。'python data 実装' の検索とは異なります。)
  • ただいまサイドメニューのテスト中/ただいまサイドメニューのテスト中
  • ただいまサイドメニューのテスト中/ただいまサイドメニューのテスト中
  • ただいまサイドメニューのテスト中/ただいまサイドメニューのテスト中
  • ただいまサイドメニューのテスト中/ただいまサイドメニューのテスト中
  • ただいまサイドメニューのテスト中/ただいまサイドメニューのテスト中
  • ただいまサイドメニューのテスト中/ただいまサイドメニューのテスト中
  • ただいまサイドメニューのテスト中/ただいまサイドメニューのテスト中
  • ただいまサイドメニューのテスト中/ただいまサイドメニューのテスト中
  • ただいまサイドメニューのテスト中/ただいまサイドメニューのテスト中
  • ただいまサイドメニューのテスト中/ただいまサイドメニューのテスト中
  • ただいまサイドメニューのテスト中/ただいまサイドメニューのテスト中
>>
fluent_python

【 Fluent Python + coding challenge 】List の List を作るときには要注意!! 投稿一覧へ戻る

Published 2020年11月23日17:16 by mootaro23

SUPPORT UKRAINE

- Your indifference to the act of cruelty can thrive rogue nations like Russia -

問題 ( 制限時間: 5 分 ):


[1] * 3 という式で [1, 1, 1] というリストを取得することが出来ます。


では、[[1, 1, 1], [1, 1, 1], [1, 1, 1]] という list の list を取得するための式を記述してください。



簡単ですね。


[1] * 3 を3つ含むリストを作ればいいんです。


nest_list = [[1] * 3] * 3


print(nest_list)

# [[1, 1, 1], [1, 1, 1], [1, 1, 1]]



はい、出来ました。


それでは皆さん、ごきげんよう。


って、本当に大丈夫ですか?


今作ったリストのリストの [1][2] の要素の値を変えてみましょう。


nest_list[1][2] = 3

print(nest_list)

# [[1, 1, 3], [1, 1, 3], [1, 1, 3]]



???


これが本当に望んでいる結果ですか?


[[1, 1, 1], [1, 1, 3], [1, 1, 1]]、<= こうなってほしいんじゃないですか?


では、やり直しです。


問題 ( 制限時間: 5 分 ):


[[1, 1, 1], [1, 1, 1], [1, 1, 1]] という list の list を取得するための式を記述してください。


出来上がったリストのリストの [1][2] の要素に 3 を代入した場合、


[[1, 1, 1], [1, 1, 3], [1, 1, 1]] という結果にならなければいけません。



リスト内包表記 ( list comprehension ) を利用しましょう。


nest_list = [[1] * 3 for _ in range(3)]


print(nest_list)

# [[1, 1, 1], [1, 1, 1], [1, 1, 1]]


nest_list[1][2] = 3

print(nest_list)

# [[1, 1, 1], [1, 1, 3], [1, 1, 1]]



大丈夫ですね。


実は、最初の間違えを for 文で書き直すと、次のようなことをやっていることと同じなんです。


inner_list = [1] * 3
outer_list = []
for _ in range(3):
outer_list.append(inner_list)


print(outer_list)

# [[1, 1, 1], [1, 1, 1], [1, 1, 1]]


outer_list[1][2] = 3


print(outer_list)

# [[1, 1, 3], [1, 1, 3], [1, 1, 3]]



つまり、外側のリストの中に含まれている [1, 1, 1] というリストの実体は 1 つだけで、外側のリストはそのリストへの参照を 3 つ含んでいるだけなんですね。


これに対して、正解の書式を for 文を利用して書き直してみると次のようになります。


outer_list = []
for _ in range(3):
inner_list = [1] * 3
outer_list.append(inner_list)


print(outer_list)

# [[1, 1, 1], [1, 1, 1], [1, 1, 1]]


outer_list[1][2] = 3


print(outer_list)

# [[1, 1, 1], [1, 1, 3], [1, 1, 1]]



その都度新しい [1, 1, 1] というリストを作成して outer_list に追加しているんです。


気をつけましょう!
この記事に興味のある方は次の記事にも関心を持っているようです...
- People who read this article may also be interested in following articles ... -
【 Effective Python, 2nd Edition + coding challenge 】プログラム開発のどの段階で並列処理 ( concurrency ) が必要になるのだろう? そのときどのようにリファクタリング ( refactoring ) していけばいいのだろう? を考えてみるシリーズ ( のはず ) 第1回
Python coding challenge - 重複のない数値セットにおける全ての組み合わせを求めよう!
Python coding challenge [解説編]: Basics of Graph Theory Part.3 - Representation and Manipulation of Trees (グラフ理論の基礎総復習 その3 - ツリーの表現と操作) 🔒
【 Python + Kivy で Android 】仕事の合間企画! Python で Kivy を使って GUI ストップウォッチを作って、python-for-android と Buildozer を使って Android APK にしてスマホで動かしてみた、もちろん Windows 上でも動きます、Mac? 多分、でも試してないから分からない、の巻
Python coding challenge - 無向グラフにおいて閉路 (cycle) を形成している辺 (edge) を見つけて connected-acyclic グラフ == ツリーにしよう!
【 Effective Python, 2nd Edition + coding challenge 】プログラムを並列処理 ( concurrency ) パターンへ移行するタイミングとツールを考えるシリーズ 第2回 - Conway's Game of Life coding challenge の実装例と課題、の巻
【Python 雑談・雑学 + coding challenge】シーケンス ( sequence ) における インデックス ( index ) を使った要素 1 つの取り出しと、スライス ( slice ) を利用した場合の取り出しの違いをちゃんと理解していますか?