Help us understand the problem. What is going on with this article?

for for ∞ for python

More than 1 year has passed since last update.

C言語とかはfor(;;)とかで無限ループできるらしいですが、pythonのfor文でも出来ます。気をつけて下さい。動作確認はpython3でやってますが、python2とかでも起きるはずです。
あと、普通に無限ループしたい場合はwhile True:を使ってください。

方法

for文が参照しているリストをループ内で増やす。

サンプルコード

from time import pause # これなしで無限ループを試す度胸ないです

# 参照するリストの初期化
loop = [0]

# 無限ループ
for i in loop:
    print(i)
    pause(0.5)
    loop.append(i+1)

適当なあたりで切り上げて下さい。

対策

ただループするつもりが、無限ループになっちゃった!というのはとても怖いので、対策をお伝えしておきます。

リストをコピーした上でfor文に渡して下さい。

# 有限ループ
for i in loop[:]:
    print(i)
    pause(0.5)
    loop.append(i+1)

注意:対策になってそうでなってない奴

loop2 = loop

# 無限ループ
for i in loop2:
    print(i)
    pause(0.5)
    loop.append(i+1)

これ、一旦loop2にコピーしているので問題なさそうに見えますが、loopに要素を追加すると、loop2にも追加されます。
リスト型はシャローコピーなのです。
下のは問題ありません。[:]をつけるとディープコピーしてくれるので。

loop2 = loop[:]

# 有限ループ
for i in loop2:
    print(i)
    pause(0.5)
    loop.append(i+1)

リストのディープコピーについて

コメントを受けて調べ直したところ、[:]はディープコピーとは違うことがわかりました。
4種類のリストのコピーとその違いを紹介します。

before = [[1,2,3], [4,5,6]]

以下の四つです。

  • そのままコピー
  • スライス([:])を使う
  • list()を使う
  • copy.deepcopyを使う

そのまま代入

after_eq = before

ここで、after_eqbeforeidを調べてみましょう

id(after_eq) == id(before)
# => True

これはどういうことか、というと、ある特定の配列が二つの変数で扱える状態です。
それが嬉しいかはわかりません。

スライス([:])やlist()を使う

この二つは結果が同じです。

after_sl = before[:]
id(after_sl) == id(before)
# => False

after_ls = list(before)
id(after_sl) == id(before)
# => False

このように、スライスやlist()を使うと全く別のリストがコピー出来たように思います。しかし、

id(after_sl[0]) == id(before[0])
# => True

id(after_ls[0]) == id(before[0])
# => True

となります。つまり、これは一層下はシャローコピーと言うことです。
これがどういう意味かは、以下の例も参考にして考えてみて下さい。

zero = [[0]]
zeros = zero*3
print(zeros)
# => [[0], [0], [0]]
zeros[0][0] = '0'
print(zeros)
# =>[['0'], ['0'], ['0']]

copy.deepcopyを使う

1番安全なのは、標準ライブラリ内のcopy.deepcopyを使うことだと思います。

import copy

after_dc = copy.deepcopy(before)

id(after_dc) == id(before)
# => False

id(after_dc[0]) == id(before[0])
# => False

これこそがディープコピーというものです。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした