for文における無限リストの生成発生 ~python学習1.03~


for文で無限ループに陥る

Pythonのfor文はC言語のものとは違うらしい。


qiita1.py

>>> words = ['Haruka', 'Lovely', 'Morishima']

>>> for w in words:
... if len(w) > 7:
... words.insert(0, w)

>>> print(words)


これは無限ループが発生し、


qiita2.py

>>> words = ['Haruka', 'Lovely', 'Morishima']

>>> for w in words[:]:
... if len(w) > 7:
... words.insert(0, w)

>>> print(words)
['Morishima', 'Haruka', 'Lovely', 'Morishima']


では、無限ループが発生しません。


なぜ無限ループが発生しないか

qiita1.pyでは、words配列そのものを渡していますが、

qiita2.pyでは、words配列の参照をコピーして渡しています。

参照を渡した場合ではinsert()されても、words[:]から得た配列を扱っているため無限ループは発生しません。

words[1:]だと、['Lovely', 'Morishima'] のみです。

つまり、words[:]では、同じ値を持つ別の配列がコピーされて渡されているということではないでしょうか。

無限ループが発生する、配列そのものを渡した場合には、'Morishima'でinsert()が行われ、

配列の要素が1つずつ後ろに下がります。これにより、for文で再度おなじ'Morishima'が

評価されることで無限ループが発生します。

Javaでシングルスレッド環境でも、for文からListの要素を変更すると、

java.util.ConcurrentModificationException例外が投げられるのは

やさしい世界だったのかもしれない。


開発環境

Windows10 64bit

Python 3.7.1

PyCharm 2018.3.2


参考資料

学習に用いているものとして、以下の2つがメインです。

詳細! Python 3 入門ノート

Python公式ドキュメント