51
46

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Python で多重ループを回避する

Last updated at Posted at 2017-05-10

はじめに

以前 Array#product で多重ループを回避しよう という Ruby の記事を投稿しました。この記事では Array#product を利用して多重ループを単一ループに変える1方法を紹介しています。最近は個人的に Python に傾倒しているので、この言語ではどう書けるかを探ってみました。

変更前のサンプルコード

python
for year in range(2010, 2013):
  for i in range(1, 3):
    for char in ('a', 'b', 'c'):
      print(year, i, char)
stdout
2010 1 a
2010 1 b
2010 1 c
2010 2 a
2010 2 b
2010 2 c
2011 1 a
2011 1 b
2011 1 c
2011 2 a
2011 2 b
2011 2 c
2012 1 a
2012 1 b
2012 1 c
2012 2 a
2012 2 b
2012 2 c

方法 1: itertools.product() を使う

Ruby の Array#product と同様に Python にも itertools.product() というデカルト積 (直積) を求めるための関数があります。

python
from itertools import product

years = range(2010, 2013)
integers = range(1, 3)
chars = ('a', 'b', 'c')

for year, i, char in product(years, integers, chars):
  print(year, i, char)

方法 2: 内包表記を使う

ネストした内包表記も利用できます。

python
years = range(2010, 2013)
integers = range(1, 3)
chars = ('a', 'b', 'c')

combinations = [(year, i, char)
                for year in years
                for i in integers
                for char in chars]

for year, i, char in combinations:
  print(year, i, char)

おまけ: Ruby の場合

ruby
years = Array(2010..2012)
integers = Array(1..2)
chars = Array('a'..'c')

years.product(integers, chars) { |year, i, char| puts("#{year} #{i} #{char}") }

参考

  1. あくまで見かけ上の話で、ループ構文によるインデントを複数から 1 つにすることです。内部的なループ回数や計算量が減るわけではありません。

51
46
4

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
51
46

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?