#
3. 形式ばらない Python の紹介

以下の例では、入力と出力は ("`>`>`>` " や "`...` ") といった プロンプトがあるかないかで区別します: 例どおりに実行するなら、 プロンプトが表示されているときに、例中のプロンプトよりも後ろの内容全てを タイプ入力しなければなりません; プロンプトが先頭にない行はインタプリタ からの出力です 3.1。

例中には二次プロンプトだけが表示されている行がありますが、これは 空行を入力しなければならないことを意味するので注意してください; 空行の入力は複数の行からなる命令の終わりをインタプリタに教えるために 使われます。

このマニュアルにある例の多くは、対話プロンプトで入力されるものでも コメントを含んでいます。Python におけるコメント文はハッシュ文字 "`#`" で始まり、物理行の終わりまで続きます。 コメントは行の先頭にも、空白やコードの後にも書くことができますが、 文字列リテラル (string literal) の内部に置くことはできません。 文字列リテラル中のハッシュ文字はただのハッシュ文字です。

例:

    # これは１番目のコメント
    SPAM = 1                 # そしてこれは２番目のコメント
                             # ... そしてこれは３番目!
    STRING = "# これはコメントではありません。"

#
3.1 Python を電卓として使う

それでは、簡単な Python コマンドをいくつか試しましょう。 インタプリタを起動して、 一次プロンプト、"`>`>`>` " が現れるのを待ちます。 (そう長くはかからないはずです)

##
3.1.1 数

インタプリタは単純な電卓のように動作します: 式をタイプ入力することができ、その結果が書き出されます。 式の文法は素直なものです: 演算子 `+`, `-`, `*`, `/` は (Pascal や C といった) 他のほとんどの言語と同じように動作します。 括弧をグループ化に使うこともできます。例えば:

    >>> 2+2
    4
    >>> # これはコメント
    ... 2+2
    4
    >>> 2+2  # そしてこれはコードと同じ行にあるコメント
    4
    >>> (50-5*6)/4
    5
    >>> # 整数の除算は floor (実数の解を越えない最大の整数) を返す:
    ... 7/3
    2
    >>> 7/-3
    -3

C と同じく、等号 ("`=`") を使って変数に値を代入します。 代入された値は書き出されません:

    >>> width = 20
    >>> height = 5*9
    >>> width * height
    900

複数の変数に同時に値を代入することができます:

    >>> x = y = z = 0  # x と y と z をゼロにする
    >>> x
    0
    >>> y
    0
    >>> z
    0

浮動小数点は完全にサポートしています; 被演算子の型が混合されているときには、 演算子は整数の被演算子を浮動小数点型に変換します。

    >>> 3 * 3.75 / 1.5
    7.5
    >>> 7.0 / 2
    3.5

複素数もサポートされています。虚数は接尾辞 "`j`" または "`J`" を 付けて書き表します。ゼロでない実数部をもつ複素数は "`(real+imagj)`" のように書き表すか、 "`complex(real, imag)`" 関数で生成できます。

    >>> 1j * 1J
    (-1+0j)
    >>> 1j * complex(0,1)
    (-1+0j)
    >>> 3+1j*3
    (3+3j)
    >>> (3+1j)*3
    (9+3j)
    >>> (1+2j)/(1+1j)
    (1.5+0.5j)

複素数は、常に実部と虚部に相当する二つの浮動小数点数で表されます。 複素数 z からそれぞれの部分を取り出すには、`z.real` と `z.imag` を使います。

    >>> a=1.5+0.5j
    >>> a.real
    1.5
    >>> a.imag
    0.5

数値を浮動小数点数や整数へに変換する関数 (`float()`, `int()`, `long()`) は複素数に対しては動作しません -- 複素数を実数に変換する方法には、ただ一つの正解というものがないからです。 絶対値 (magnitude) を (浮動小数点数として) 得るには `abs(z)` を 使い、実部を得るには `z.real` を使ってください。

    >>> a=3.0+4.0j
    >>> float(a)
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    TypeError: can't convert complex to float; use abs(z)
    >>> a.real
    3.0
    >>> a.imag
    4.0
    >>> abs(a)  # sqrt(a.real**2 + a.imag**2)
    5.0
    >>>

対話モードでは、最後に印字された式は変数 `_` に代入されます。 このことを利用すると、 Python を電卓として使うときに、計算を連続して 行う作業が多少楽になります。以下に例を示します:

    >>> tax = 12.5 / 100
    >>> price = 100.50
    >>> price * tax
    12.5625
    >>> price + _
    113.0625
    >>> round(_, 2)
    113.06
    >>>

ユーザはこの変数を読取り専用の値として扱うべきです。 この変数に明示的な代入を行ってはいけません -- そんなことをすれば、 この組み込み変数と同じ名前で、元の組み込み変数の不思議な動作を覆い隠して しまうような、別個のローカルな変数が生成されてしまいます。

##
3.1.2 文字列

数のほかに、Python は文字列も操作できます。 文字列はいくつもの方法で表現できます。 文字列はシングルまたはダブルのクォートで囲みます。

    >>> 'spam eggs'
    'spam eggs'
    >>> 'doesn\'t'
    "doesn't"
    >>> "doesn't"
    "doesn't"
    >>> '"Yes," he said.'
    '"Yes," he said.'
    >>> "\"Yes,\" he said."
    '"Yes," he said.'
    >>> '"Isn\'t," she said.'
    '"Isn\'t," she said.'

文字列リテラルはいくつもかの方法で複数行にまたがって記述することが できます。継続行を使うことができ、これには行の末尾の文字を バックスラッシュにします。こうすることで、次の行が現在の行と論理的に 継続していることを示します:

    hello = "This is a rather long string containing\n\
    several lines of text just as you would do in C.\n\
        Note that whitespace at the beginning of the line is\
     significant."

    print hello

`\n` を使って文字列に改行位置を埋め込まなくてはならないことに注意 してください; 末尾のバックスラッシュの後ろにある改行文字は無視されます。 従って、上の例は以下のような出力を行います:

    This is a rather long string containing
    several lines of text just as you would do in C.
        Note that whitespace at the beginning of the line is significant.

一方、文字列リテラルを ``raw'' 文字列にすると、`\n` のような エスケープシーケンスは改行に変換されません。逆に、行末のバックスラッシュ やソースコード中の改行文字が文字列データに含められます。つまり、以下の例:

    hello = r"This is a rather long string containing\n\
    several lines of text much as you would do in C."

    print hello

は、以下のような出力を行います:

    This is a rather long string containing\n\
    several lines of text much as you would do in C.

また、対になった三重クォート `"""` または `'`'`'` で 文字列を囲むこともできます。 三重クォートを使っているときには、行末をエスケープする必要はありません、 しかし、行末の改行文字も文字列に含まれることになります。

    print """
    Usage: thingy [OPTIONS]
         -h                        Display this usage message
         -H hostname               Hostname to connect to
    """

は以下のような出力を行います:

    Usage: thingy [OPTIONS]
         -h                        Display this usage message
         -H hostname               Hostname to connect to

インタプリタは、文字列演算の結果を、タイプ入力する時のと同じ方法で 出力します: 文字列はクオート文字で囲い、クオート文字自体やその他の 奇妙な文字は、正しい文字が表示されるようにするために バックスラッシュでエスケープします。 文字列がシングルクオートを含み、かつダブルクオートを含まない場合には、 全体をダブルクオートで囲います。そうでない場合にはシングルクオートで 囲みます。 (後で述べる `print` を使って、クオートやエスケープ のない文字列を書くことができます。)

文字列は `+` 演算子で連結させる (くっつけて一つにする) ことができ、 `*` 演算子で反復させることができます。

    >>> word = 'Help' + 'A'
    >>> word
    'HelpA'
    >>> '<' + word*5 + '>'
    '<HelpAHelpAHelpAHelpAHelpA>'

互いに隣あった二つの文字列リテラルは自動的に連結されます: 例えば、上記の最初の行は "`word = 'Help' 'A'`" と書くことも できました; この機能は二つともリテラルの場合にのみ働くもので、 任意の文字列表現で使うことができるわけではありません。

    >>> 'str' 'ing'             #  <-  これは ok
    'string'
    >>> 'str'.strip() + 'ing'   #  <-  これは ok
    'string'
    >>> 'str'.strip() 'ing'     #  <-  これはダメ
      File "<stdin>", line 1, in ?
        'str'.strip() 'ing'
                      ^
    SyntaxError: invalid syntax

文字列は添字表記 (インデクス表記) することができます; C 言語と同じく、文字列の最初の文字の添字 (インデクス) は 0 となります。 独立した文字型というものはありません; 単一の文字は、単に サイズが 1 の文字列です。Icon 言語と同じく、部分文字列を スライス表記: コロンで区切られた二つのインデクスで指定する ことができます。

    >>> word[4]
    'A'
    >>> word[0:2]
    'He'
    >>> word[2:4]
    'lp'

スライスのインデクスには便利なデフォルト値があります; 最初のインデクスを省略すると、0 と見なされます。 第 2 のインデクスを省略すると、スライスしようとする文字列のサイズと みなされます。

    >>> word[2:]    # 先頭の２文字以外全て
    'He'
    >>> word[:-2]    # 末尾の２文字を除くすべて
    'lpA'

C 言語の文字列と違い、Python の文字列は変更できません。 インデクス指定された文字列中のある位置に代入を行おうとすると エラーになります:

    >>> word[0] = 'x'
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    TypeError: object doesn't support item assignment
    >>> word[:1] = 'Splat'
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    TypeError: object doesn't support slice assignment

一方、要素どうしを組み合わせた新たな文字列の生成は、簡単で効率的です:

    >>> 'x' + word[1:]
    'xelpA'
    >>> 'Splat' + word[4]
    'SplatA'

スライス演算には便利な不変式があります: `s[:i] + s[i:]` は `s` に等しくなります。

    >>> word[:2] + word[2:]
    'HelpA'
    >>> word[:3] + word[3:]
    'HelpA'

スライス表記に行儀の悪いインデクス指定をしても、値はたしなみよく処理 されます: インデクスが大きすぎる場合は文字列のサイズと置き換えられます。 スライスの下境界 (文字列の左端) よりも小さいインデクス値を上境界 (文字列の右端) に指定すると、空文字列が返されます。

    >>> word[1:100]
    'elpA'
    >>> word[10:]
    ''
    >>> word[2:1]
    ''

インデクスを負の数にして、右から数えることもできます。 例えば:

    >>> word[-1]     # 最後の文字
    'A'
    >>> word[-2]     # 最後から二つめの文字
    'p'
    >>> word[-2:]    # 最後の２文字
    'pA'
    >>> word[:-2]    # 最後の２文字を除くすべて
    'Hel'

-0 は 0 と全く同じなので、右から数えることができません。 注意してください!

    >>> word[-0]     # (-0 は 0 に等しい)
    'H'

負で、かつ範囲外のインデクスをスライス表記で行うと、インデクス は切り詰められます。しかし、単一の要素を指定する (スライスでない) インデクス指定でこれを行ってはいけません:

    >>> word[-100:]
    'HelpA'
    >>> word[-10]    # エラー
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    IndexError: string index out of range

スライスの働きかたをおぼえる最も良い方法は、 インデクスが文字と文字のあいだ (between) を指しており、最初の 文字の左端が 0 になっていると考えることです。そうすると、 n 文字からなる文字列中の最後の文字の右端はインデクス n となります。例えば:

     +---+---+---+---+---+
     | H | e | l | p | A |
     +---+---+---+---+---+
     0   1   2   3   4   5
    -5  -4  -3  -2  -1

といった具合です。

数が記された行のうち、最初の方の行は、文字列中のインデクス 0...5 の 位置を表します; 次の行は、対応する負のインデクスを表しています。 i から j までのスライスは、それぞれ i, j とラベル付けされたけられた端点間のすべての文字からなります。

非負のインデクス対の場合、スライスされた配列の長さは、スライスの両端の インデクスが境界内にあるかぎり、インデクス間の差になります。 例えば、 `word[1:3]` の長さは 2 になります。

組込み関数 `len()` は文字列の長さ (length) を返します。

    >>> s = 'supercalifragilisticexpialidocious'
    >>> len(s)
    34

参考資料:

配列型
  次節で記述されている文字列および Unicode 文字列は 配列型 の例であり、配列型でサポートされている共通の操作を サポートしています。

文字列メソッド
  文字列や Unicode 文字列では、基本的な変換や検索を 行うための数多くのメソッドをサポートしています。

文字列フォーマット操作
  文字列や Unicode 文字列が `%` 演算子の左被演算子 である場合に呼び出されるフォーマット操作については、ここで詳しく記述 されています。

##
3.1.3 Unicode 文字列

Python 2.0 から、プログラマはテキスト・データを格納するための新しい データ型、Unicode オブジェクトを利用できるようになりました。 Unicode オブジェクトを使うと、Unicode データ (http://www.unicode.org/ 参照) を記憶したり、操作したりできます。また、 Unicode オブジェクトは 既存の文字列オブジェクトとよく統合していて、必要に応じた自動変換機能を 提供しています。

Unicode には、古今のテキストで使われているあらゆる書き文字のあらゆる 文字について、対応付けを行うための一つの序数を規定しているという利点が あります。 これまでは、書き文字のために利用可能な序数は 256 個しかなく、テキストは 書き文字の対応付けを行っているコードページに束縛されているのが通常 でした。 このことは、とりわけソフトウェアの国際化 (通常 "`i18n`" -- "`i`" + 18 文字 + "`n`" の意) に対して大きな 混乱をもたらしました。Unicode では、すべての書き文字に対して単一の コードページを定義することで、これらの問題を解決しています。

Python では、Unicode 文字列の作成は通常の文字列を作成するのと 同じように単純なものです:

    >>> u'Hello World !'
    u'Hello World !'

クオートの前にある小文字の "`u`" は、Unicode 文字列を生成 することになっていることを示します。文字列に特殊な文字を 含めたければ、Python の Unicode-Escape エンコーディングを 使って行えます。以下はその方法を示しています:

    >>> u'Hello\u0020World !'
    u'Hello World !'

エスケープシーケンス `\u0020` は、序数の値 0x0020 を持つ Unicode 文字 (スペース文字) を、指定場所に挿入することを示します。

他の文字は、それぞれの序数値をそのまま Unicode の序数値に用いて 解釈されます。多くの西洋諸国で使われている標準 Latin-1 エンコーディング のリテラル文字列があれば、Unicode の下位 256 文字が Latin-1 の 256 文字と同じになっていて便利だと思うことでしょう。

上級者のために、通常の文字列の場合と同じく raw モードもあります。 これには、文字列を開始するクオート文字の前に 'ur' を付けて、 Python に Raw-Unicode-Escape エンコーディングを使わせ なければなりません。このモードでは、上記の `\uXXXX` の 変換は機能、小文字の 'u' の前に奇数個のバックスラッシュがあるときにだけ 適用されます。

    >>> ur'Hello\u0020World !'
    u'Hello World !'
    >>> ur'Hello\\u0020World !'
    u'Hello\\\\u0020World !'

raw モードは、正規表現を記述する時のように、沢山のバックスラッシュを 入力しなければならないときとても役に立ちます。

これら標準のエンコーディングにとは別に、Python では、既知の 文字エンコーディングに基づいて Unicode 文字列を生成する一連の 手段を提供しています。

組込み関数 `unicode()` は、 登録されているすべての Unicode codecs (COder: エンコーダ と DECoder デコーダ) へのアクセス機能を提供します。codecs が変換できる エンコーディングには、よく知られているものとして Latin-1, ASCII, UTF-8 および UTF-16 が あります。後者の二つは可変長のエンコードで、各 Unicode 文字を 1 バイトまたはそれ以上のバイト列に保存します。デフォルトのエンコーディング は通常 ASCIIに設定されています。ASCIIでは 0 から 127 の範囲の 文字だけを通過させ、それ以外の文字は受理せずエラーを出します。 Unicode 文字列を印字したり、ファイルに書き出したり、 `str()` で変換すると、デフォルトのエンコーディングを 使った変換が行われます。

    >>> u"abc"
    u'abc'
    >>> u"あいう"
    u'\x82\xa0\x82\xa2\x82\xa4'
    >>> str(u"あいう")
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-5:
    ordinal not in range(128)

特定のエンコーディングを使って Unicode 文字列を 8 ビットの文字列に 変換するために、Unicode オブジェクトでは `encode()` メソッドを提供しています。このメソッドは単一の引数として エンコーディングの名前をとります。エンコーディング名には 小文字の使用が推奨されています。

    >>> u"あいう".encode('utf-8')
    '\xc2\x82\xc2\xa0\xc2\x82\xc2\xa2\xc2\x82\xc2\xa4'

特定のエンコーディングで書かれているデータがあり、そこから Unicode 文字列を生成したいなら、`unicode()` を使い、 第 2 引数にエンコーディング名を指定します。

    unicode('\xc2\x82\xc2\xa0\xc2\x82\xc2\xa2\xc2\x82\xc2\xa4', 'utf-8')
    u'\x82\xa0\x82\xa2\x82\xa4'

##
3.1.4 リスト

Python は数多くの 複合 (compound) データ型を備えており、 別々の値を一まとめにするために使えます。 最も汎用的なデータ型は リスト (list) で、コンマで区切られた 値からなるリストを各カッコで囲んだものとして書き表されます。 リストの要素をすべて同じ型にする必要はありません。

    >>> a = ['spam', 'eggs', 100, 1234]
    >>> a
    ['spam', 'eggs', 100, 1234]

文字列のインデクスと同じく、リストのインデクスは 0 から開始します。 また、スライス、連結なども行えます:

    >>> a[0]
    'spam'
    >>> a[3]
    1234
    >>> a[-2]
    100
    >>> a[1:-1]
    ['eggs', 100]
    >>> a[:2] + ['bacon', 2*2]
    ['spam', 'eggs', 'bacon', 4]
    >>> 3*a[:3] + ['Boe!']
    ['spam', 'eggs', 100, 'spam', 'eggs', 100, 'spam', 'eggs', 100, 'Boe!']

変化不可能 (immutable) な文字列型と違い、 リストは個々の要素を変更することができます。

    >>> a
    ['spam', 'eggs', 100, 1234]
    >>> a[2] = a[2] + 23
    >>> a
    ['spam', 'eggs', 123, 1234]

スライスに代入することもできます。スライスの代入を行って、 リストのサイズを変更することさえできます。

    >>> # いくつかの項目を置換する:
    ... a[0:2] = [1, 12]
    >>> a
    [1, 12, 123, 1234]
    >>> # いくつかの項目を除去する:
    ... a[0:2] = []
    >>> a
    [123, 1234]
    >>> # いくつかの項目を挿入する:
    ... a[1:1] = ['bletch', 'xyzzy']
    >>> a
    [123, 'bletch', 'xyzzy', 1234]
    >>> a[:0] = a     # それ自身 (のコピー) を先頭に挿入する
    >>> a
    [123, 'bletch', 'xyzzy', 1234, 123, 'bletch', 'xyzzy', 1234]

組込み関数 `len()` はリストにも適用できます。

    >>> len(a)
    8

リストを入れ子にする (ほかのリストを含むリストを造る) ことも可能です。 例えば、

    >>> q = [2, 3]
    >>> p = [1, q, 4]
    >>> len(p)
    3
    >>> p[1]
    [2, 3]
    >>> p[1][0]
    2
    >>> p[1].append('xtra')     # 5.1節を参照
    >>> p
    [1, [2, 3, 'xtra'], 4]
    >>> q
    [2, 3, 'xtra']

最後の例では、 `p[1]` と `q` が実際には同一のオブジェクトを 参照していることに注意してください! オブジェクトの意味付け (semantics) については、後ほど触れることに します。

#
3.2 プログラミングへの第一歩

もちろん、2 たす 2 よりももっと複雑な仕事にも Python を使うことが できます。Fibonacci 級数列の先頭の部分列は次のようにして 書くことができます:

    >>> # Fibonacci 級数:
    ... # 二つの要素の和が次の要素を定義する
    ... a, b = 0, 1
    >>> while b < 10:
    ...       print b
    ...       a, b = b, a+b
    ...
    1
    1
    2
    3
    5
    8

上の例では、いくつか新しい機能を取り入れています。

- 最初の行には 複数同時の代入 (multiple assignment) が入っています: 変数 `a` と `b` は、それぞれ同時に新しい値 0 と 1 に なっています。この代入は最後の行でも再度使われており、代入が 行われる前に右辺の式がまず評価されます。右辺の式は左から右へと 順番に評価されます。

- `while` は、条件 (ここでは `b < 10`) が真である限り 実行を繰り返し (ループし) ます。Python では、C 言語と同様に、ゼロでない 整数値は真となり、ゼロは偽です。条件式は文字列値やリスト値、 実際には任意の配列型でもかまいません。例中で使われている条件テスト は単なる比較です。標準的な比較演算子は C 言語と同様です: すなわち、 `<` (より小さい)、 `>` (より大きい)、 `==` (等しい)、 `<=` (より小さいか等しい)、 `>=` (より大きいか等しい)、 および `!=` (等しくない) 、 です。

- ループの本体 (body) はインデント (indent, 字下げ) されています: インデントは Python において実行文をグループにまとめる 方法です。Python は (いまだに!) 賢い入力行編集機能を提供していないので、 インデントされた各行を入力するにはタブや (複数個の) スペースを 使わなければなりません。実際には、Python へのより複雑な入力を準備する にはテキストエディタを使うことになるでしょう; ほとんどのテキスト エディタは自動インデント機能を持っています。 複合文を対話的に入力するときには、(パーザはいつ最後の行を入力 したのか推し量ることができないので) 入力の完了を示すために最後に空行を 続けなければなりません。基本ブロックの各行は同じだけインデントされて いなければならないので注意してください。

- `print` は指定した (1 つまたは複数の) 式の値を書き出します。 `print` は、(電卓の例でしたように) 単に値を出力したい式を書くの とは、複数の式や文字列を扱う方法が違います。 文字列は引用符無しで出力され、複数の要素の間にはスペースが挿入されるので、 以下のように出力をうまく書式化できます。

      >>> i = 256*256
      >>> print 'The value of i is', i
      The value of i is 65536

  末尾にコンマを入れると、出力を行った後に改行されません:

      >>> a, b = 0, 1
      >>> while b < 1000:
      ...     print b,
      ...     a, b = b, a+b
      ...
      1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987

  インタプリタは、最後に入力した行がまだ完全な文になっていない場合、 改行をはさんで次のプロンプトを出力することに注意してください。

... からの出力です 3.1
  入力と出力を区別するために異なるフォントを使おうとは思うのですが、 それに必要な LaTeX の hack 作業に必要な量が、今のところ私の能力を 超えています。