coLinux日記

coLinuxはフリーソフトを種として、よろずのシステムとぞなれりける。

SimplePrograms で Python を学ぶ + リスト内包表記

2024-07-19 22:01:26 | Python
SimplePrograms 18 lines のプログラムの中にある、
return 文が返すものを「リスト内包表記(List Comprehensions)」と言うのですね。

    return [solution+[(n,i+1)]
       for i in range(BOARD_SIZE)
          for solution in smaller_solutions
             if not under_attack(i+1, solution)]


Python のチュートリアルに使い方が書いてあります。
https://docs.python.org/ja/3/tutorial/datastructures.html#list-comprehensions
----------
squares = [x**2 for x in range(10)]

これはより簡潔で読みやすいです。

リスト内包表記は、括弧の中の 式、 for 句、そして0個以上の for か if 句で構成されます。 リスト内包表記の実行結果は、 for と if 句のコンテキスト中で式を評価した結果からなる新しいリストです。
----------


このリスト内包表記の例は、これと同じです。

----------
>>> squares = []
>>> for x in range(10):
... squares.append(x**2)
...
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
----------


ここで、append() は、次のようなリストデータ型のメソッドですね。
https://docs.python.org/ja/3/tutorial/datastructures.html#more-on-lists

----------
list.append(x)
リストの末尾に要素を一つ追加します。a[len(a):] = [x] と等価です。
----------


つまり、インストールしたばかりの Python 3.12.4 で試すと、
>>> s = []
>>> s
[]
>>> s.append(2)
>>> s
[2]
>>> s.append(4)
>>> s
[2, 4]
>>>
>>> len(s)
2
>>> s[len(s):] = [6]
>>> s
[2, 4, 6]
>>>
ですね。

と言うことで、18 lines のリスト内包表記は、

括弧の中の式: solution+[(n,i+1)]
for 句: for i in range(BCARD_SIZE)
そして、1個の for 句 : for solution in smaller_solutions
その中の if 句 : if not under_attack(i+1, solution)


という構造ですね。これは、先ほどの tutorial の

---------
例えば、次のリスト内包表記は2つのリストの要素から、違うもの同士をペアにします。
>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

これは次のコードと等価です:
>>> combs = []
>>> for x in [1,2,3]:
... for y in [3,1,4]:
... if x != y:
... combs.append((x, y))
...
>>> combs
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

for と if 文が両方のコードで同じ順序になっていることに注目してください。
----------

の例と一緒ですね。

ちなみに、
>>> vec = [-4 , -2, 0, 2, 4]
>>> [x*2 for x in vec ]
[-8, -4, 0, 4, 8]
>>> x
Traceback (most recent call last):
File "<stdin&gh;", line 1, in <module>
NameError: name 'x' is not defined
>>>
なので、リスト内包表記内で生成された変数は外では使えないようです。

また、リスト内包表記をGemini に聞いたら、

ここから--------------
メリット
* forループと条件分岐を一行で記述できるため、コードが簡潔になる
* 読みやすく、処理内容が直感的に理解しやすい
* 効率的にリストを作成できる
--------------ここまで

とメリットを上げていて、まとめとして、

ここから--------------
リスト内包表記は、Python初心者にとって最初は少し難しく感じるかもしれませんが、慣れてくると非常に便利で強力なツールになります。
--------------ここまで

と言っているので、積極的に使った方が良さそうです。SimplePrograms に使ったのも、そんな意図がありそうで、Python 入門者もこれを使って慣れておきたいと思いました。
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする