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

以下のサンプルでは、入力と出力はプロンプト(*>>>* や *...*)の有無で区別
します: 例を実際に試す場合は、プロンプトが表示されているときに、サンプ
ル中のプロンプトから後ろの内容全てを入力します。

このマニュアルにあるサンプルの多くは、対話プロンプトで入力されるもので
もコメントを含んでいます。 Python におけるコメント文は、ハッシュ文字
"#" で始まり、物理行の終わりまで続きます。コメントは行の先頭にも、空白
やコードの後にも書くことができますが、文字列リテラルの内部に置くことは
できません。文字列リテラル中のハッシュ文字はただのハッシュ文字です。コ
メントはコードを明快にするためのものであり、Pythonはコメントを解釈しま
せん。なので、サンプルコードを実際に入力して試して見るときは、コメント
を省いても大丈夫です。

いくつかの例です:

   # this is the first comment
   spam = 1  # and this is the second comment
             # ... and now a third!
   text = "# This is not a comment because it's inside quotes."


3.1. Python を電卓として使う
============================

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


3.1.1. 数
---------

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

   >>> 2 + 2
   4
   >>> 50 - 5*6
   20
   >>> (50 - 5*6) / 4
   5.0
   >>> 8 / 5  # division always returns a floating point number
   1.6

整数 (例えば、 "2" 、 "4" 、 "20") は "int" 型であり、小数部を持つ数 (
例えば、 "5.0" 、 "1.6") は "float" 型です。数値型については後のチュー
トリアルでさらに見ていきます。

除算 ("/") は常に浮動小数点数を返します。 "//" 演算子は *整数除算* を
行い、(小数部を切り捨てた) 整数値を返します; 剰余は、"%" で求めます。:

   >>> 17 / 3  # classic division returns a float
   5.666666666666667
   >>>
   >>> 17 // 3  # floor division discards the fractional part
   5
   >>> 17 % 3  # the % operator returns the remainder of the division
   2
   >>> 5 * 3 + 2  # result * divisor + remainder
   17

Python では、冪乗を計算するのに "**" 演算子が使えます [1]:

   >>> 5 ** 2  # 5 squared
   25
   >>> 2 ** 7  # 2 to the power of 7
   128

等号 ("=") は変数に値を代入します。代入を行っても、結果は出力されず、
次の入力プロンプトだけが表示されます。:

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

"定義" されていない (つまり値が代入されていない) 変数を使おうとすると
、エラーが発生します:

   >>> n  # try to access an undefined variable
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   NameError: name 'n' is not defined

浮動小数点を完全にサポートしています。演算対象の値(オペランド)に複数の
型が入り混じっている場合、演算子は整数のオペランドを浮動小数点型に変換
します:

   >>> 4 * 3.75 - 1
   14.0

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

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

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

"int" と "float" に加え、 Python は "Decimal" や "Fraction" などの他の
数値型もサポートしています。 Python はビルトインで 複素数 もサポートし
、 "j" もしくは "J" 接尾辞を使って虚部を示します (例。 "3+5j")。


3.1.2. 文字列型 (string)
------------------------

Python は、数だけではなく、文字列も操作できます。文字列を記述する方法
は複数あり、単引用符 ("'...'") で囲むか、もしくは二重引用符 (""..."")
で囲みます。結果はどちらも同じ文字列になります。[2] 引用符は、"\" でエ
スケープできます。:

   >>> 'spam eggs'  # single quotes
   'spam eggs'
   >>> 'doesn\'t'  # use \' to escape the single quote...
   "doesn't"
   >>> "doesn't"  # ...or use double quotes instead
   "doesn't"
   >>> '"Yes," they said.'
   '"Yes," they said.'
   >>> "\"Yes,\" they said."
   '"Yes," they said.'
   >>> '"Isn\'t," they said.'
   '"Isn\'t," they said.'

対話的インタプリタでは、出力文字列は引用符に囲まれ、特殊文字はバックス
ラッシュでエスケープされます。出力文字が入力とは違って見える (囲ってい
る引用符が変わる) こともありますが、その 2 つの文字列は同じ文字列です
。文字列が単引用符を含み二重引用符を含まない場合、二重引用符で囲われ、
それ以外の場合は単引用符で囲われます。

   >>> '"Isn\'t," they said.'
   '"Isn\'t," they said.'
   >>> print('"Isn\'t," they said.')
   "Isn't," they said.
   >>> s = 'First line.\nSecond line.'  # \n means newline
   >>> s  # without print(), \n is included in the output
   'First line.\nSecond line.'
   >>> print(s)  # with print(), \n produces a new line
   First line.
   Second line.

"\" に続く文字を特殊文字として解釈されたくない場合は、最初の引用符の前
に "r" を付けた *raw strings* が使えます:

   >>> print('C:\some\name')  # here \n means newline!
   C:\some
   ame
   >>> print(r'C:\some\name')  # note the r before the quote
   C:\some\name

文字列リテラルは複数行にまたがって書けます。1 つの方法は三連引用符
(""""..."""" や "'''...'''") を使うことです。改行文字は自動的に文字列
に含まれますが、行末に "\" を付けることで含めないようにすることもでき
ます。次の例:

   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

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

   >>> # 3 times 'un', followed by 'ium'
   >>> 3 * 'un' + 'ium'
   'unununium'

連続して並んでいる複数の *文字列リテラル* (つまり、引用符に囲われた文
字列) は、自動的に連結されます。

   >>> 'Py' 'thon'
   'Python'

この機能は、長い文字列を改行したいときにとても役に立ちます:

   >>> text = ('Put several strings within parentheses '
   ...         'to have them joined together.')
   >>> text
   'Put several strings within parentheses to have them joined together.'

これは 2 つのリテラルどうしに対してのみ働き、変数や式には働きません:

   >>> prefix = 'Py'
   >>> prefix 'thon'  # can't concatenate a variable and a string literal
     ...
   SyntaxError: invalid syntax
   >>> ('un' * 3) 'ium'
     ...
   SyntaxError: invalid syntax

変数どうしや変数とリテラルを連結したい場合は、"+" を使ってください:

   >>> prefix + 'thon'
   'Python'

文字列は *インデックス* (添字) を指定して文字を取得できます。最初の文
字のインデックスは 0 になります。文字を表す、専用のデータ型は用意され
ていません; 文字とは、単に長さが 1 の文字列です:

   >>> word = 'Python'
   >>> word[0]  # character in position 0
   'P'
   >>> word[5]  # character in position 5
   'n'

インデックスには、負の値も指定できまます。この場合、右から数えていきま
す:

   >>> word[-1]  # last character
   'n'
   >>> word[-2]  # second-last character
   'o'
   >>> word[-6]
   'P'

-0 は 0 と区別できないので、負のインデックスは -1 から始まります。

インデックスに加え、*スライス* もサポートされています。インデックスは
一文字づつ取得するのに使いますが、*スライス* は部分文字列を取得します:

   >>> word[0:2]  # characters from position 0 (included) to 2 (excluded)
   'Py'
   >>> word[2:5]  # characters from position 2 (included) to 5 (excluded)
   'tho'

開始値は常に含まれ、終了値は常に含まれないことに注意してください。なの
で "s[:i] + s[i:]" は常に "s"  と等しくなります:

   >>> word[:2] + word[2:]
   'Python'
   >>> word[:4] + word[4:]
   'Python'

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

   >>> word[:2]   # character from the beginning to position 2 (excluded)
   'Py'
   >>> word[4:]   # characters from position 4 (included) to the end
   'on'
   >>> word[-2:]  # characters from the second-last (included) to the end
   'on'

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

    +---+---+---+---+---+---+
    | P | y | t | h | o | n |
    +---+---+---+---+---+---+
    0   1   2   3   4   5   6
   -6  -5  -4  -3  -2  -1

1行目の数字は文字列の 0 から 6 までのインデックスの位置を示しています;
2行目は対応する負のインデックスを示しています。*i* から *j* までのスラ
イスは、それぞれ *i* と付いた境界から *j* と付いた境界までの全ての文字
から成っています。

正のインデックスの場合、スライスされたシーケンスの長さは、スライスの両
端のインデックスが範囲内にあるかぎり、インデックス間の差になります。例
えば、 "word[1:3]" の長さは 2 になります。

大き過ぎるインデックスを使おうとするとエラーが発生します:

   >>> word[42]  # the word only has 6 characters
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   IndexError: string index out of range

しかし、スライスで範囲外のインデックスを使ったときは、上手く対応して扱
ってくれます:

   >>> word[4:42]
   'on'
   >>> word[42:]
   ''

Python の文字列は変更できません -- つまり不変 (*immutable*) です。従っ
て、文字列のインデックスで指定したある場所に代入を行うとエラーが発生し
ます:

   >>> word[0] = 'J'
     ...
   TypeError: 'str' object does not support item assignment
   >>> word[2:] = 'py'
     ...
   TypeError: 'str' object does not support item assignment

元の文字列と別の文字列が必要な場合は、新しく文字列を作成してください:

   >>> 'J' + word[1:]
   'Jython'
   >>> word[:2] + 'py'
   'Pypy'

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

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

参考:

  テキストシーケンス型 --- str
     文字列は代表的な *シーケンス型* で、シーケンス型でサポートされて
     いる共通の操作をサポートしています。

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

  フォーマット済み文字列リテラル
     式の埋め込みをサポートした文字列リテラル

  書式指定文字列の文法
     "str.format()" を使った文字列のフォーマットについての情報がありま
     す。

  printf 形式の文字列書式化
     文字列が "%" 演算子の左オペランドである場合に呼び出される古いフォ
     ーマット操作について、詳しく記述されています。


3.1.3. リスト型 (list)
----------------------

Pythonは多くの *複合 (compound)* データ型を備えており、複数の値をまと
めるのに使われます。最も汎用性が高いのは *リスト (list)* で、コンマ区
切りの値 (要素) の並びを角括弧で囲んだものとして書き表されます。リスト
は異なる型の要素を含むこともありますが、通常は同じ型の要素のみを持ちま
す。

   >>> squares = [1, 4, 9, 16, 25]
   >>> squares
   [1, 4, 9, 16, 25]

文字列 (や他の全ての組み込みのシーケンス (*sequence*) 型) のように、リ
ストはインデックスやスライスができます:

   >>> squares[0]  # indexing returns the item
   1
   >>> squares[-1]
   25
   >>> squares[-3:]  # slicing returns a new list
   [9, 16, 25]

全てのスライス操作は、指定された要素を含む新しいリストを返します。例え
ば、次のスライスは、リストの新しい (浅い) コピーを返します。:

   >>> squares[:]
   [1, 4, 9, 16, 25]

リストは、リストの連結などもサポートしています:

   >>> squares + [36, 49, 64, 81, 100]
   [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

不変 (*immutable*) な文字列とは違って、リストは可変 (*mutable*) 型です
ので、要素を入れ替えられます。:

   >>> cubes = [1, 8, 27, 65, 125]  # something's wrong here
   >>> 4 ** 3  # the cube of 4 is 64, not 65!
   64
   >>> cubes[3] = 64  # replace the wrong value
   >>> cubes
   [1, 8, 27, 64, 125]

"append()" を使って、リストの末尾に新しい要素を追加できます (このメソ
ッドについては後で詳しく見ていきます):

   >>> cubes.append(216)  # add the cube of 6
   >>> cubes.append(7 ** 3)  # and the cube of 7
   >>> cubes
   [1, 8, 27, 64, 125, 216, 343]

スライスには、代入もできます。スライスの代入で、リストのサイズを変更し
たり、全てを削除したりもできます:

   >>> letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
   >>> letters
   ['a', 'b', 'c', 'd', 'e', 'f', 'g']
   >>> # replace some values
   >>> letters[2:5] = ['C', 'D', 'E']
   >>> letters
   ['a', 'b', 'C', 'D', 'E', 'f', 'g']
   >>> # now remove them
   >>> letters[2:5] = []
   >>> letters
   ['a', 'b', 'f', 'g']
   >>> # clear the list by replacing all the elements with an empty list
   >>> letters[:] = []
   >>> letters
   []

組込み関数 "len()" はリストにも使えます:

   >>> letters = ['a', 'b', 'c', 'd']
   >>> len(letters)
   4

リストを入れ子 (ほかのリストを含むリストを造る) にできます。例えば:

   >>> a = ['a', 'b', 'c']
   >>> n = [1, 2, 3]
   >>> x = [a, n]
   >>> x
   [['a', 'b', 'c'], [1, 2, 3]]
   >>> x[0]
   ['a', 'b', 'c']
   >>> x[0][1]
   'b'


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

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

   >>> # Fibonacci series:
   ... # the sum of two elements defines the next
   ... 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 言語と同様に、ゼロでない整数値は真と
  なり、ゼロは偽です。条件式には、文字列値やリスト値なども使えます。そ
  れ以外のシーケンスも、条件式として使用できます。長さが 1 以上のシー
  ケンスは真で、空のシーケンスは偽になります。サンプルで使われている条
  件テストはシンプルな比較です。標準的な比較演算子は C 言語と同様です:
  すなわち、 "<" (より小さい)、 ">" (より大きい)、 "==" (等しい)、
  "<=" (より小さいか等しい)、 ">=" (より大きいか等しい)、および "!=" (
  等しくない)、です。

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

* "print()" 関数は、与えられた引数の値を書き出します。これは (前に電卓
  の例でやったような) 単に出力したい式を書くのとは、複数の引数や浮動小
  数点量や文字列に対する扱い方が違います。"print()" 関数では、文字列は
  引用符無しで出力され、要素の間に空白が挿入されて、このように出力の書
  式が整えられます:

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

  キーワード引数 *end* を使うと、出力の末尾に改行文字を出力しないよう
  にしたり、別の文字列を末尾に出力したりできます:

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

-[ 脚注 ]-

[1] "**" は "-" より優先順位が高いので、"-3**2" は "-(3**2)" と解釈さ
    れ、計算結果は "-9" になります。これを避けて "9" を得たければ、
    "(-3)**2" と書けば良いです。

[2] 他の言語と違って、"\n" のような特殊文字は単引用符 ("'...'") と二重
    引用符 (""..."") で同じ意味を持ちます。両者の唯一の違いは、単引用
    符で囲われた箇所では """ をエスケープする必要がない (ただし "\'"
    はエスケープする必要がある) ことで、逆もまた同様です。
