paloma blog

NWエンジニアやってます。主に自宅環境のお遊びを書きます。Pythonもちょっと。タイトルは好きなカクテルから。

pythonのリスト内包表記内でprintするとNoneが帰ってくるけどこれは何だ?

最近NW設計でサブネットを計算するときにipcalcではなくpythonのipaddressモジュールを使ってます。
prefix内のサブネットが一気に出せて便利です。 昔は各Prefixのサブネットも暗記してましたが、pythonで一発で出せるのでもう覚える気が無くなってしまいましたw

リスト内包表記が便利です

python3系で実行してます。

Python 3.8.3 (tags/v3.8.3:6f8c832, May 13 2020, 22:20:19) [MSC v.1925 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> import ipaddress

サブネット分けの構文を使っただけだとgenerator objectが返ってきて中身が見えません。

>>> ipaddress.IPv4Network('10.0.0.0/24').subnets(new_prefix=26)
<generator object _BaseNetwork.subnets at 0x0307D990>

ループさせれば見えますが、pythonのプロンプト内でサクッと計算したいところです。
こういう時はリスト内包表記にすると値も見れますので便利です。

>>> [x for x in ipaddress.IPv4Network('10.0.0.0/24').subnets(new_prefix=26)]
[IPv4Network('10.0.0.0/26'), IPv4Network('10.0.0.64/26'), IPv4Network('10.0.0.128/26'), IPv4Network('10.0.0.192/26')]

リストで帰って来るのはいいんですが、他の資料にコピペ出来るよう値だけ取り出したいですよね。
という訳でprintを挟んだものがこちら。

>>> [print(x) for x in ipaddress.IPv4Network('10.0.0.0/24').subnets(new_prefix=26)]
10.0.0.0/26
10.0.0.64/26
10.0.0.128/26
10.0.0.192/26
[None, None, None, None]

値が出たのはいいですが、リスト内がNoneになっている。なんだこれ?

困ったらまずは公式ドキュメント

5. データ構造 — Python 3.8.8 ドキュメント

リスト内包表記は英語だとlist comprehensiveと言う様です。
簡素にリスト作成が出来る機能ですと。

これのアプリケーションの用途イメージがいまいちわかりませんが、私の様にgenerate objectの中身を見たいときは便利です。

しかし、なぜNoneが返ってくるかはわかりませんでした。

Stack Overflowで調べる

日本だとTeratailがありますが、やはり英語サイトの方がナレッジも多いので活用してます。
今回の件もバッチリ出てきました。

Understanding Python 3 lists printing None value for each element - Stack Overflow

Noneはprint関数の戻り値の様です。
print関数のreturnがNoneなので今回のリストはNoneが返ってくるということですね。
printはBuiltin関数なのでこういうものだと納得できますが、 値が出力されている部分はリスト内包表記がどう処理してるんですかね?謎が深まります。

謎ばかりを追っていても仕方ないので、Noneの件は一旦仕様ということで落とします。
また、リスト内包表記でprintをするのはよろしくなくて、forループをワンライナーで書くのが良いようです。
(何故良くないかは調べられてませんが)

>>> for x in ipaddress.IPv4Network('10.0.0.0/24').subnets(new_prefix=26) : print(x)
...
10.0.0.0/26
10.0.0.64/26
10.0.0.128/26
10.0.0.192/26

これだとワンライナーで書けるしスッキリですね。

まとめ

プログラミング言語は奥深く、今回の件一つ取っても謎が謎を呼び完全に理解できる回答にたどり着くのは大変です。
pythonに関してはなんとなく書けるようになり自分のやりたいことも実装できるようになってきましたが、
今回の様な事象が潜んでいると思うと極めるのは非常に難しそうですね。

でもこういうトラブルシュートも楽しかったりします。