LoginSignup
1
1

Pythonの反復処理いろいろ

Last updated at Posted at 2023-11-10

はじめに

Pythonの反復処理関連の関数、ライブラリについてまとめる。

関数/ライブラリ 内容
range 反復処理の範囲を指定する。
reversed 逆順で反復処理する。
enumerate 反復処理のインデックスを付ける。
zip 複数の配列や辞書をまとめて反復処理する。
generator/yield 順次、値を返答する処理関数。
tqdm 反復処理の進捗状況を表示するライブラリ。
itertools 反復処理の強化ライブラリ。

range

反復処理の範囲を指定して使う。range(stop)で終わりを指定して使うか、range(start,stop)で開始と終わりを指定して使うことができる。range(start,stop,step)としてあげればステップも指定可能。

range_test.py
test_data=[]
#0→10 1ステップ
for i in range(10):
	test_data.append(i)
	
print(f'# {type(test_data) = } / {len(test_data) = } / {test_data = }')
# type(test_data) = <class 'list'> / len(test_data) = 10 / test_data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

test_data.clear()
#2→10 1ステップ
for i in range(2,10):
	test_data.append(i)
	
print(f'# {type(test_data) = } / {len(test_data) = } / {test_data = }')
# type(test_data) = <class 'list'> / len(test_data) = 8 / test_data = [2, 3, 4, 5, 6, 7, 8, 9]


test_data.clear()
#2→10 2ステップ
for i in range(2,10,2):
	test_data.append(i)
	
print(f'# {type(test_data) = } / {len(test_data) = } / {test_data = }')
# type(test_data) = <class 'list'> / len(test_data) = 4 / test_data = [2, 4, 6, 8]


test_data.clear()
#10→0 -1ステップ
for i in range(10,0,-1):
	test_data.append(i)
	
print(f'# {type(test_data) = } / {len(test_data) = } / {test_data = }')
# type(test_data) = <class 'list'> / len(test_data) = 10 / test_data = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

戻る

reversed

逆順で反復処理する。

reversed_test.py
test_data=['A','B','C','D','E','F','G','H','I','J']

for d in reversed(test_data):
	print(f'# {d = }')
# d = 'J'
# d = 'I'
# d = 'H'
# d = 'G'
# d = 'F'
# d = 'E'
# d = 'D'
# d = 'C'
# d = 'B'
# d = 'A'

戻る

enumerate

反復処理のインデックスを付ける。インデックスの開始位置も指定できる。

enumerate_test.py
test_data=['A','B','C','D','E','F','G','H','I','J']

#0~
for i,d in enumerate(test_data):
	print(f'# {i = } / {d = }')
# i = 0 / d = 'A'
# i = 1 / d = 'B'
# i = 2 / d = 'C'
# i = 3 / d = 'D'
# i = 4 / d = 'E'
# i = 5 / d = 'F'
# i = 6 / d = 'G'
# i = 7 / d = 'H'
# i = 8 / d = 'I'
# i = 9 / d = 'J'

#2~
for i,d in enumerate(test_data,2):
	print(f'# {i = } / {d = }')
# i = 2 / d = 'A'
# i = 3 / d = 'B'
# i = 4 / d = 'C'
# i = 5 / d = 'D'
# i = 6 / d = 'E'
# i = 7 / d = 'F'
# i = 8 / d = 'G'
# i = 9 / d = 'H'
# i = 10 / d = 'I'
# i = 11 / d = 'J'

戻る

zip

複数の配列や辞書をまとめて反復処理する。複数を一つにまとめて、tuple化することもできる。enumerateとセットで使うことも可能。

zip.py
test_data=['a','b','c','d','e','f','g','h','i','j']
test_data2=['A','B','C','D','E','F','G','H','I','J']

for d1,d2 in zip(test_data, test_data2):
	print(f'# {d1 = } / {d2 = }')
# d1 = 'a' / d2 = 'A'
# d1 = 'b' / d2 = 'B'
# d1 = 'c' / d2 = 'C'
# d1 = 'd' / d2 = 'D'
# d1 = 'e' / d2 = 'E'
# d1 = 'f' / d2 = 'F'
# d1 = 'g' / d2 = 'G'
# d1 = 'h' / d2 = 'H'
# d1 = 'i' / d2 = 'I'
# d1 = 'j' / d2 = 'J'

for d in zip(test_data, test_data2):
	print(f'# {type(d) = } / {d = }')
# type(d) = <class 'tuple'> / d = ('a', 'A')
# type(d) = <class 'tuple'> / d = ('b', 'B')
# type(d) = <class 'tuple'> / d = ('c', 'C')
# type(d) = <class 'tuple'> / d = ('d', 'D')
# type(d) = <class 'tuple'> / d = ('e', 'E')
# type(d) = <class 'tuple'> / d = ('f', 'F')
# type(d) = <class 'tuple'> / d = ('g', 'G')
# type(d) = <class 'tuple'> / d = ('h', 'H')
# type(d) = <class 'tuple'> / d = ('i', 'I')
# type(d) = <class 'tuple'> / d = ('j', 'J')

for i,(d1,d2) in enumerate(zip(test_data, test_data2)):
	print(f'# {i = } / {d1 = } / {d2 = }')
# i = 0 / d1 = 'a' / d2 = 'A'
# i = 1 / d1 = 'b' / d2 = 'B'
# i = 2 / d1 = 'c' / d2 = 'C'
# i = 3 / d1 = 'd' / d2 = 'D'
# i = 4 / d1 = 'e' / d2 = 'E'
# i = 5 / d1 = 'f' / d2 = 'F'
# i = 6 / d1 = 'g' / d2 = 'G'
# i = 7 / d1 = 'h' / d2 = 'H'
# i = 8 / d1 = 'i' / d2 = 'I'
# i = 9 / d1 = 'j' / d2 = 'J'

for i,d in enumerate(zip(test_data, test_data2)):
	print(f'# {i = } / {type(d) = } / {d = }')
# i = 0 / type(d) = <class 'tuple'> / d = ('a', 'A')
# i = 1 / type(d) = <class 'tuple'> / d = ('b', 'B')
# i = 2 / type(d) = <class 'tuple'> / d = ('c', 'C')
# i = 3 / type(d) = <class 'tuple'> / d = ('d', 'D')
# i = 4 / type(d) = <class 'tuple'> / d = ('e', 'E')
# i = 5 / type(d) = <class 'tuple'> / d = ('f', 'F')
# i = 6 / type(d) = <class 'tuple'> / d = ('g', 'G')
# i = 7 / type(d) = <class 'tuple'> / d = ('h', 'H')
# i = 8 / type(d) = <class 'tuple'> / d = ('i', 'I')
# i = 9 / type(d) = <class 'tuple'> / d = ('j', 'J')

戻る

generator/yield

yieldは、関数のreturnの代わりとなるもので、関数内の処理を一時中断、返答する機能。generatorは、yieldを使った関数のことをいう。generator内の変数はyieldで中断した時の値を保持できる。generatorの戻り値は、generator型なので=で取り出しても、そのまま値として処理できない。list()でリスト化するか、forの反復処理で値を取り出す。いまいち用途が思い浮かばずいい例が書けなかった。。

generator_yield_test.py
#--------------------------
# yieldを使ったgenerator関数
#--------------------------
def generator_func():
	for i in range(10):
		yield i
print(f'# {type(generator_func()) = }\n# {generator_func() = }')
# type(generator_func()) = <class 'generator'>
# generator_func() = <generator object generator_func at 0x00000207D6EBA900>

# list()でリスト化
print(f'# {list(generator_func()) = }')
# list(generator_func()) = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# for で値取り出し
for i in generator_func():
	print(f'# {i=}')
# i=0
# i=1
# i=2
# ~
# i=8
# i=9

戻る

tqdm

進捗状況をプログレスバーで表示する。長ーい処理がいつ終わるのか?を目視で確認できるので、重宝するライブラリ。下記は例なので長くない処理。zipやenumerateでtqdmを使うと、プログレスバーが出なくなる。その場合はtotal=で反復処理のサイズを指定してあげればプログレスバーが表示される。

tqdm_test.py
from tqdm import tqdm

#基本----------------------------------------------
test_data=['a','b','c','d','e','f','g','h','i','j']
for i in tqdm(test_data):
	pass
# 100%|██████████████████████████████████████████████████████████████████████████████████████| 1000/1000 [00:00<?, ?it/s]



#zipやenumerateと一緒にtqdm使う 1-------------------
test_data=['a','b','c','d','e','f','g','h','i','j']
test_data2=['A','B','C','D','E','F','G','H','I','J']

for i,(d1,d2) in tqdm( enumerate(zip(test_data, test_data2)) ):
	pass
#10it [00:00, ?it/s]



#zipやenumerateと一緒にtqdm使う 2-------------------
for i,(d1,d2) in tqdm( enumerate(zip(test_data, test_data2)) , total=len(test_data)):
	pass
# 100%|██████████████████████████████████████████████████████████████████████████████████████| 1000/1000 [00:00<?, ?it/s]

戻る

itertools

こういう反復処理したいんだけどな、という処理を実現できる、かゆいところに手の届くライブラリ。色々あるが、自分がよく使うだろうなという例を記載する。

公式サイトは下記

ツール 内容
itertools.zip_longest( ,filevalue=<値>) zip処理した時に、要素数が足りない方に任意の値を埋める。fillvalueに埋めたい値を設定。
itertools.islice(...,start,stop,step) 開始(start),終了(stop),ステップ(step)を指定して反復処理する。使用しないパラメータはNoneを設定する。zipとも組みあせて使用することができる。
itertools_test.py
import itertools

# itertools.zip_longest()
test_data=['a','b','c','d']
test_data2=['A','B','C','D','E','F','G','H','I','J']
for d1, d2 in itertools.zip_longest(test_data, test_data2, fillvalue='-'):
	print(f'# {d1 = } / {d2 = }')
# d1 = 'a' / d2 = 'A'
# d1 = 'b' / d2 = 'B'
# d1 = 'c' / d2 = 'C'
# d1 = 'd' / d2 = 'D'
# d1 = '-' / d2 = 'E'
# d1 = '-' / d2 = 'F'
# d1 = '-' / d2 = 'G'
# d1 = '-' / d2 = 'H'
# d1 = '-' / d2 = 'I'
# d1 = '-' / d2 = 'J'

# itertools.islice()
test_data=['0','1','2','3','4','5','6','7','8','9']
test_data2=['A','B','C','D','E','F','G','H','I','J']
# start=0, stop =5
for d1, d2 in itertools.islice( zip(test_data, test_data2) , None,5):
	print(f'# {d1 = } / {d2 = }')
# d1 = '0' / d2 = 'A'
# d1 = '1' / d2 = 'B'
# d1 = '2' / d2 = 'C'
# d1 = '3' / d2 = 'D'
# d1 = '4' / d2 = 'E'

# start=2, stop =5
for d1, d2 in itertools.islice( zip(test_data, test_data2) , 2, 5):
	print(f'# {d1 = } / {d2 = }')
# d1 = '2' / d2 = 'C'
# d1 = '3' / d2 = 'D'
# d1 = '4' / d2 = 'E'

# start=2, stop =end
for d1, d2 in itertools.islice( zip(test_data, test_data2) , 2, None):
	print(f'# {d1 = } / {d2 = }')
# d1 = '2' / d2 = 'C'
# d1 = '3' / d2 = 'D'
# d1 = '4' / d2 = 'E'
# d1 = '5' / d2 = 'F'
# d1 = '6' / d2 = 'G'
# d1 = '7' / d2 = 'H'
# d1 = '8' / d2 = 'I'
# d1 = '9' / d2 = 'J'

# start=0, stop =end, step=2
for d1, d2 in itertools.islice( zip(test_data, test_data2) , None, None, 2):
	print(f'# {d1 = } / {d2 = }')
# d1 = '0' / d2 = 'A'
# d1 = '2' / d2 = 'C'
# d1 = '4' / d2 = 'E'
# d1 = '6' / d2 = 'G'
# d1 = '8' / d2 = 'I'

戻る


参考にした記事、サイト

1
1
0

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
1
1