1.2.3. 制御フロー

コードが実行される順序を制御します.

1.2.3.1. if/elif/else

>>> if 2**2 == 4:
... print('Obvious!')
...
Obvious!

ブロックの範囲はインデントで決まります

ちなみに

以下の行を Python インタプリタで打ち込んで下さい, ただし インデントの深さに注意してください ipython はコロン記号 : の後に自動的にインデントを深くします; インデントを減らすにはバックスペースキーでスペース4つ分移動します. 論理ブロックを抜けるためには2回エンターキーを押します.

>>> a = 10
>>> if a == 1:
... print(1)
... elif a == 2:
... print(2)
... else:
... print('A lot')
A lot

インデントはスクリプトを書く場合も必須です. 練習問題として, 上の行の内容を同じインデントで condition.py というスクリプトに打ち込んで ipython から run condition.py としてスクリプトを実行してみましょう.

1.2.3.2. for/range

インデクスで反復する:

>>> for i in range(4):
... print(i)
0
1
2
3

しかし多くの場合, 値に対して反復した方が読みやすいでしょう:

>>> for word in ('cool', 'powerful', 'readable'):
... print('Python is %s' % word)
Python is cool
Python is powerful
Python is readable

1.2.3.3. while/break/continue

典型的な C 形式の while ループ (Mandelbrot の問題):

>>> z = 1 + 1j
>>> while abs(z) < 100:
... z = z**2 + 1
>>> z
(-134+352j)

より進んだ機能

break for/while ループの中から抜ける:

>>> z = 1 + 1j
>>> while abs(z) < 100:
... if z.imag == 0:
... break
... z = z**2 + 1

continue ループの反復を進める:

>>> a = [1, 0, 2, 4]
>>> for element in a:
... if element == 0:
... continue
... print(1. / element)
1.0
0.5
0.25

1.2.3.4. 条件式

if <OBJECT>:
偽と評価されるもの:
  • 0 に等しい数 (0, 0.0, 0+0j)

  • 空のコンテナ (list, tuple, set, dictionary, ...)

  • False, None
真と評価されるもの:
  • あらゆるもの

a == b:

論理的に等価かどうか調べる:

>>> 1 == 1.
True
a is b:

同一性を調べる: 2つのオブジェクトが同じオブジェクトかどうか:

>>> 1 is 1.
False
>>> a = 1
>>> b = 1
>>> a is b
True
a in b:

データの集まり b の中に a が含まれているか:

>>> b = [1, 2, 3]
>>> 2 in b
True
>>> 5 in b
False

b が辞書の場合, 辞書のキーに a が含まれているか調べます.

1.2.3.5. 高度に反復

1.2.3.5.1. あらゆる シーケンス に対する反復

あらゆるシーケンスに対して反復できます(文字列, リスト, 辞書のキー, ファイル中の行, ...):

>>> vowels = 'aeiouy'
>>> for i in 'powerful':
... if i in vowels:
... print(i)
o
e
u
>>> message = "Hello how are you?"
>>> message.split() # returns a list
['Hello', 'how', 'are', 'you?']
>>> for word in message.split():
... print(word)
...
Hello
how
are
you?

ちなみに

整数やインデクスでなく, あらゆるものに対してループできる言語は(特に科学技術計算向きの言語では)少数です. Python を使うことで, インデクスについて注意深く考えない為に起きる問題に悩まされることはなくなり, まさに興味あるオブジェクトに対してループできるようになります。この機能はコードを読みやすくするのによく利用されます。

警告

反復しているシーケンスを変更するのは危険です.

1.2.3.5.2. 反復回数を追跡する

シーケンスの反復中に反復回数を追跡することはよくあります.

  • 以下のような, カウンタ付きの while や for ループを使うこともできます:

    >>> words = ('cool', 'powerful', 'readable')
    
    >>> for i in range(0, len(words)):
    ... print((i, words[i]))
    (0, 'cool')
    (1, 'powerful')
    (2, 'readable')
  • しかし, Python はこのために enumerate 組み込み関数を提供しています:

    >>> for index, item in enumerate(words):
    
    ... print((index, item))
    (0, 'cool')
    (1, 'powerful')
    (2, 'readable')

1.2.3.5.3. 辞書を使ったループ

items を使う:

>>> d = {'a': 1, 'b':1.2, 'c':1j}
>>> for key, val in sorted(d.items()):
... print('Key: %s has value: %s' % (key, val))
Key: a has value: 1
Key: b has value: 1.2
Key: c has value: 1j

注釈

辞書の並びはランダムなので sorted() を利用しています、この関数はキーに対してソートします。

1.2.3.6. リスト内包表記

>>> [i**2 for i in range(4)]
[0, 1, 4, 9]

練習問題

Wallis の公式を使って, Pi の値を計算しましょう:

\[\pi = 2 \prod_{i=1}^{\infty} \frac{4i^2}{4i^2 - 1}\]