LoginSignup
2
2

More than 3 years have passed since last update.

Pythonでmapオブジェクトのforループは一度しかできない

Last updated at Posted at 2020-12-20

こういう事になります。

str_list = ["1", "2", "3"]

int_map = map(lambda i: int(i), str_list)

for i in int_map:
  print("map1回目", i)

for i in int_map:
  print("map2回目", i) #=> ここだけ出力されない

int_list = list(map(lambda i: int(i), str_list))

for i in int_list:
  print("list1回目", i)

for i in int_list:
  print("list2回目", i)

出力

map1回目 1
map1回目 2
map1回目 3
list1回目 1
list1回目 2
list1回目 3
list2回目 1
list2回目 2
list2回目 3

環境

  • python 3.6.9
  • Google Colaboratory

解説

Listオブジェクトは何度でもforでループできます。

int_list = [1,2,3]

for i in int_list:
  print("list1回目", i)

for i in int_list:
  print("list2回目", i)

出力

list1回目 1
list1回目 2
list1回目 3
list2回目 1
list2回目 2
list2回目 3

これを、map()関数のイテレータオブジェクトで行うと、

str_list = ["1", "2", "3"]

int_map = map(lambda i: int(i), str_list)

for i in int_map:
  print("map1回目", i)

for i in int_map:
  print("map2回目", i) #=> ここだけ出力されない

一度めのforしか通りません。

map1回目 1
map1回目 2
map1回目 3

Python公式ドキュメントによると

(list のような) コンテナオブジェクトは、自身を iter() 関数にオブジェクトに渡したり for ループ内で使うたびに、新たな未使用のイテレータを生成します。これをイテレータで行おうとすると、前回のイテレーションで使用済みの同じイテレータオブジェクトを単純に返すため、空のコンテナのようになってしまします。

とのことです。イテレータとしてみると、list等のコンテナオブジェクトの方が特殊な挙動なんですね。

実際に中身を確認してみると

str_list = ["1", "2", "3"]
int_map = map(lambda i: int(i), str_list)

for i in int_map:
  print("map1回目", i)

print(list(int_map))
map1回目 1
map1回目 2
map1回目 3
[]

forを通った後の中身は空になっていました。

ちなみに、forだけでなくlist()を一度でも呼ぶと空になります。

str_list = ["1", "2", "3"]
int_map = map(lambda i: int(i), str_list)

print(list(int_map))

for i in int_map:
  print("map1回目", i) #=> ここは出力されない
[1, 2, 3]
2
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2