こういう事になります。
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]