Python の便利な関数 itertools.repeat() とは?使い方や応用例を徹底解説!

Python の itertools モジュールには、開発を効率化するさまざまな関数が含まれています。その中でも、同じ値を繰り返し返すイテレータを提供する itertools.repeat() は、意外と知られていない便利な機能です。この記事では、基本的な使い方から実践的な応用例、さらにはパフォーマンスやメモリ効率についても深掘りしていきます!

looping stairs

itertools.repeat() とは?

まずは、基本的な構文を見てみましょう。

import itertools

itertools.repeat(object, times=None)

引数の説明

  • object: 繰り返し返される値。
  • times: 繰り返しの回数(省略可能)。設定しなければ無限に繰り返します。

基本的な使い方

まずは簡単な例から。

import itertools

for value in itertools.repeat("Hello", 3):
    print(value)

出力

Hello
Hello
Hello

この例では、"Hello" が 3 回繰り返して出力されます。もし times を省略すると、無限に繰り返されるので注意が必要です。

実用例: データ処理に活用する

itertools.repeat() は、データ処理や関数の引数として利用する場合に特に便利です。

例1: map() と組み合わせて使う

リストの要素をすべて 2 乗したい場合、itertools.repeat() を使うことで簡潔に書くことができます。

import itertools

numbers = [1, 2, 3, 4, 5]
squared = map(pow, numbers, itertools.repeat(2))  # 各要素を2乗する

print(list(squared))

出力

[1, 4, 9, 16, 25]

解説

itertools.repeat(2)2 を繰り返し返しますが、map()numbers の長さに合わせて処理を行うため、無限に続くわけではありません。

例2: リストを定数で埋める

リストを同じ値で埋める場合、itertools.repeat() を使うとシンプルです。

import itertools

filled_list = list(itertools.repeat(0, 5))
print(filled_list)

出力

[0, 0, 0, 0, 0]

このように、5 つの 0 で構成されたリストを簡単に作成できます。

repeat() のパフォーマンスを検証してみる

同じ値を繰り返すリストを作成する方法として、リスト内包表記や * 演算子を使うこともできます。それらと比較して、itertools.repeat() がどれほど効率的か検証してみましょう。

import itertools
import time

n = 10**6

# itertools.repeat
start = time.time()
repeat_list = list(itertools.repeat(0, n))
end = time.time()
print(f"itertools.repeat: {end - start:.6f} 秒")

# List comprehension
start = time.time()
comprehension_list = [0 for _ in range(n)]
end = time.time()
print(f"リスト内包表記: {end - start:.6f} 秒")

# Multiplication operator
start = time.time()
multiplication_list = [0] * n
end = time.time()
print(f"* 演算子: {end - start:.6f} 秒")

出力例

itertools.repeat: 0.042 秒
リスト内包表記: 0.062 秒
* 演算子: 0.035 秒

解説

  • itertools.repeat() はメモリ効率が高く、大規模なデータでは特に有利です。
  • * 演算子は速度が速いものの、メモリに負荷がかかる場合があります。

イテレータとリストの違いに注意

itertools.repeat() はイテレータを返すため、リストと異なりメモリ消費が少なく済みます。ただし、sys.getsizeof() で計測できるのはイテレータ自体のサイズのみで、生成されるオブジェクトのサイズは含まれません。

メモリ比較の例

import itertools
import sys

iterator = itertools.repeat(0, 10**6)
print(f"Iterator size: {sys.getsizeof(iterator)} bytes")

list_data = [0] * 10**6
print(f"List size: {sys.getsizeof(list_data)} bytes")

出力例

Iterator size: 48 bytes
List size: 8000000 bytes

注意

  • sys.getsizeof() はイテレータのオーバーヘッドのみを計測するため、実際のメモリ使用量はさらに異なる可能性があります。

itertools.cycle() との違い

類似した関数に itertools.cycle() がありますが、こちらはシーケンス全体を無限にループします。対して repeat() は、同じオブジェクトを繰り返し返します。

例: cycle と repeat の違い

import itertools

print(list(itertools.islice(itertools.repeat(1, 5), 5)))  # [1, 1, 1, 1, 1]

print(list(itertools.islice(itertools.cycle([1, 2, 3]), 5)))  # [1, 2, 3, 1, 2]

解説

  • repeat() は単一の値を繰り返します。
  • cycle() はシーケンス全体を無限にループします。

まとめ

itertools.repeat() は、以下のような場面で便利に使えます:

  1. 同じ値を繰り返し使用したいとき
  2. メモリ効率を重視したデータ処理
  3. 関数の引数として定数を繰り返し渡したいとき

ぜひ、日々のプログラミングに取り入れてみてください。シンプルながら強力なツールで、コードの効率がアップします!

上部へスクロール