Python Strings in Google's Python Class in Japanese

Google による Python の授業 (日本語訳)/ Google's Python Class (英語原文)

資料
日本語訳: 設定/ 入門/ 文字列 / リスト/ 整列/ 辞書とファイル/ 正規表現/ ユーティリティ
英語原文: Set Up/ Introduction/ Strings/ Lists/ Sorting/ Dict and Files/ Reg. Exp./ Utilities

練習問題
日本語訳: 基本問題/ 新生児名/ 特殊なコピー/ アクセス履歴のパズル
英語原文: Basic Exercises/ Baby Names Exercise/ Copy Special Exercise/ Log Puzzle Exercise

講義映像
英語
1日目: Introduction, Strings/ Lists and Sorting/ Dicts and Files
2日目: Regular Expression/ Utilities/ Utilities urllib/ Conclusions

Python の文字列


Python には多くの使いやすい特徴を持つ, "str" という 組み込みの文字列クラスを持っています ("string" という古いモジュールもありますが, 使わないこと). 文字列定数は, 一重引用符 (シングルクォート) か二重引用符 (ダブルクォート) のどちらかで囲むことが出来ます. 一重引用符がより広く使われています. バックスラッシュは, 例えば \n \' \" のように, 一重か二重引用符の中にある定数では普通通りに使えます. 二重引用符に囲まれた文字列定数は, 一重引用符をそのまま含む (例えば, "I didn't do it" と書く) ことが出来, 同様に一重引用符で囲まれた文字列は二重引用符を含むことが出来ます. 文字列定数は複数行に渡ることが出来ますが, 新しい行に続けるために各行の最後にバックスラッシュ \ が なければいけません. """ や ''' といった, 3つ並んだ引用符で囲まれた文字列定数は 複数行のテキストを受け付けます.
Python の文字列は "不変", つまり生成した後に変更することが出来ません (Java の文字列も不変の形式を取っています). 文字列は変更できないので, 計算した値を表すには *新しい* 文字列を作ります. 例えば, 式 ('hello' + 'there') は 2つの文字列 'hello', 'there' を取り, 新しい文字列 'hellothere' を作ります.
文字列に含まれる文字は, 標準的な [] の書式を使ってやり取りでき, Java や C++ のように, Python は 0 を基本とする通し番号を使います. もし文字列が 'hello' ならば, str[1] は 'e' になります. もし [] 内の番号が文字列の範囲を超えたときは, Python は エラーを発生させます. (Perl とは異なり, ) Python の流儀では, 初期値でなんとかするのではなく, 実行できないときは停止します. 手軽な "切り取り" の書式 (以下で説明) も, 文字列から任意の部分文字列を取り出すのに使えます. len(string) 関数は, 文字列の長さを返します. [ ] の書式と len() 関数は, 文字列, リストなどの任意の配列の型に使えます. Python は異なる型にかけて操作を一貫して機能させようとします. Python の初心者向けにいうと, len() 関数を使えなくならないように, "len" は変数名として 使わないこと. '+' 演算子は 2つの文字列をつなげることができます. 以下のコードでは, 変数が事前に定義されていない, つまり, 変数に値を割り当ててから使っていることに注意.
  s = 'hi'
  print s[1]          ## i
  print len(s)        ## 2
  print s + ' there'  ## hi there

Java とは違い, '+' は数字や他の型を自動的に文字列に変えることはしません. str() 関数を使って数値を文字列形式に変換することで, 他の文字列とつなげることが出来ます.
  pi = 3.14
  ##text = 'The value of pi is ' + pi      ## NO, 動きません. 
  text = 'The value of pi is '  + str(pi)  ## yes

数字に対して, 標準の演算子である +, /, * は普通どおりに機能します. ++ 演算子はありませんが, +=, -= などが使えます. 整数の割り算がしたいなら, スラッシュ記号を 2つ並べた演算子, 例えば, 6 // 5 は 1, を使うのが正確です. (Python 3000 より前は 1つのスラッシュ記号により整数対整数の除算をして いましたが, 整数による割り算をしたいなら // が良いでしょう. )
"print" 演算子は 1つ以上の値と改行記号を表示します (改行記号を出さないようにするには, 表示させるものの最後にカンマをつけること). "生の" 文字列定数は先頭に 'r' が付けられ, バックスラッシュの特別処理を行わないそのままの記号列になるので, r'x\nx' は長さ 4の文字列 'x\nx' と評価されます. 'u' という接頭辞を付けると, Unicode の文字列定数を書くことが出来ます. (Python は Unicode を支援する特徴を他にも多く持っています. 以下の文章を参照すること).
  raw = r'this\t\n and that'
  print raw     ## this\t\n and that
    
  multi = """It was the best of times.
  It was the worst of times."""

文字列のメソッド


メソッドは関数のようなものですが, オブジェクト "上" で動作します. もし変数 s が文字列なら, s.lower() はその文字列オブジェクト上で lower() メソッドを実行し, 結果を返します (このオブジェクト上で実行するメソッドの考え方は, オブジェクト指向プログラミング (OOP) を構成する基礎的な考え方のひとつです). 次に良く使われる文字列のメソッドをいくつか示します.
  • s.lower(), s.upper() -- 文字列をすべて小文字/大文字にしたものを返す.
  • s.strip() -- 文字列から最初と最後の空白を取り除いて返す.
  • s.isalpha()/s.isdigit()/s.isspace()... -- 文字列の文字がすべて, 色々な文字クラスに含まれるかを確かめる.
  • s.startswith('other'), s.endswith('other') -- 文字列が与えられた別の文字列 'other' で始まって/終わっているかを確かめる.
  • s.find('other') -- (正規表現ではない) 与えられた別の文字列 'other' を s の中で探し, あればその始まりのインデックス, ないならば -1 を返す.
  • s.replace('old', 'new') -- 'old' となっているところをすべて 'new' に置き換えた文字列を返す.
  • s.split('delim') -- 与えられた区切り文字 'delim' で分割された部分文字列のリストを返す. その区切り文字は正規表現ではなく, 単なるテキストです. 'aaa,bbb,ccc'.split(',') -> ['aaa', 'bbb', 'ccc']. 便利で特別な場合として, s.split() (引数なし) は すべての空白文字で文字列を分割します.
  • s.join(list) -- split() の逆で, 文字列を区切り文字としてリストの要素をひとつにまとめます. 例えば, '---'.join(['aaa', 'bbb', 'ccc']) -> aaa---bbb---ccc となります.

"python str" で google 検索すれば, 文字列のメソッドが列記されている公式の python.org 文字列メソッド が見つかるでしょう.
Python は文字列とは別の, 文字の型というものは持っていません. 代わりに, s[8] といった式はその文字を含む長さ 1の文字列を返します. 長さ 1の文字列には, ==, <= などの演算子すべてが期待通りに機能するので, ほとんどの場合, Python が別のスカラー "文字" 型を 持っていないことを知る必要はありません.

文字列の切り取り


切り取り (slice) の文法は文字列やリストといった配列の一部分を参照するのに手軽な方法です. 切り取り s[start:end] は start から始まり end の 1つ前までを含む要素からなる配列です. s = "Hello" とすると, 次のようになります.
Hello
01234
-5-4-3-2-1

the string 'hello' with letter indexes 0 1 2 3 4


  • s[1:4] は 'ell' -- 通し番号 1から始まり, 通し番号 4の前までの文字.
  • s[1:] は 'ello' -- 切り取りの数字の一方を省略すると, 文字列の初めか最後を表す通し番号が初期値になります.
  • s[:] is 'Hello' -- 切り取りの数字を両方省略すると, 全体のコピーになります. (これは文字列やリストのような配列をコピーする Python らしい方法です. )
  • s[1:100] is 'ello' -- 大きすぎる通し番号は文字列長まで切り捨てられます.

標準的な 0から始まる通し番号を使うと, 文字列の初めの方の文字が扱いやすくなっています. それに対して, Python では文字列の後ろの方の文字を 扱いやすくする負の数字を使います. s[-1] は最後の文字 'o', s[-2] は最後から2番目の文字 'l' となっています. 負の通し番号は, 文字列の後ろから前に戻って数えます.
  • s[-1] は 'o' -- 最後の文字 (最後から見て初めの文字).
  • s[-4] は 'e' -- 最後から4番目の文字.
  • s[:-3] は 'He' -- 最後の3文字を含まない文字列.
  • s[-3:] は 'llo' -- 後ろから3文字目から最後までの文字列.

明らかに, 任意の通し番号 n に対して, s[:n] + s[n:] == s が成り立ちます. これは n が負の数や範囲外の数でも成り立ちます. 別の見方をすると, s[:n] と s[n:] は常に すべての文字を保ったまま, 文字列を 2つに分割しています. 後のリストの節で見るように, 切り取りはリストでも使えます.

文字列の %


Python には, 文字列をひとまとめにする printf() のような道具があります. % 演算子は左側に printf 書式の文字列 (%d が整数, %s が文字列, %f/%g が浮動小数点) を, 右側のタプル内に対応する値 (タプルはカンマで区切られた値が括弧でまとめられている) を取ります.
  # % operator
  text = "%d little pigs come out or I'll %s and %s and %s" % (3, 'huff', 'puff', 'blow down')

上の行は長く見えるので, 複数行に分割したいと考えたとき, 他の言語のように '%' の後ろで行を分けることは出来ません. これは, 初期設定において Python は各行を別々の命令として扱うためです (こうしているのは, 各行にセミコロンを書く必要がなくなるからです). これを直すために全体の式を括弧で括ると, その式は 複数行に渡っても大丈夫になります. この複数行に渡るコードの技は, ( ), [ ], { } などの 様々なグループ化する道具に対して使えます.
  # add parens to make the long-line work:
  text = ("%d little pigs come out or I'll %s and %s and %s" %
    (3, 'huff', 'puff', 'blow down'))

複数言語の文字列 (Unicode)


通常の Python の文字列は Unicode では *なく*, 単純なバイトコードです. Unicode の文字列を作るには, 'u' という接頭辞を文字列定数に使うこと.
> ustring = u'A unicode \u018e string \xf1'
> ustring
u'A unicode \u018e string \xf1'

Unicode の文字列は通常の "str" 文字列とは異なる種類のオブジェクトです. しかし, Unicode の文字列は互換性があり (通常の文字列と Unicode 文字列は共通の親クラス "basestring" を共有しています), もし通常の文字列の代わりに Unicode の文字列が渡されても, 正規表現などの様々なライブラリが正しく機能します.
Unicode の文字列を 'utf-8' などの文字コードのバイトに 変換するには, ustring.encode('utf-8') メソッドを Unicode 文字列で呼ぶこと. 逆の操作については, unicode(s, encoding) 関数が 通常のコードバイトを Unicode 文字列に変換します.
## (unistring from above contains a unicode string)
> s = unistring.encode('utf-8')
> s
'A unicode \xc6\x8e string \xc3\xb1'  ## utf-8 でコード化されたバイト文字
> t = unicode(s, 'utf-8')             ## バイトコードを Unicode の文字列に戻す
> t == unistring                      ## 元と同じになります. 

True


組み込みの print は Unicode 文字列に対してきちんと動作しません. 表示するには, utf-8 か何かに encode() でまず変換すること. ファイル読み込みの節には, あるコードのテキストファイルを開く方法の例があります. Unicode の扱いについては, ここで説明した Python 2.x での振舞いに対して, Python 3000 では飛躍的に整理されています.

If 命令


Python は if, ループ, 関数などに対するコードの まとまり (block) をつくる { } を使いません. 代わりに, Python は命令をひとまとまりにするために, コロン (:) と字下げ/空白を使います. if に対する真偽値の確認を括弧の中に入れる必要はありません (C++, Java と大きく異なります), *elif* と *else* の節を 持つことができます (簡略表現: 単語 "elif" は単語 "else" と同じ長さです).
if による確認では任意の値を使うことができます. None, 0, 空の文字列, 空リスト, 空の辞書といった "ゼロ" の値はすべて偽として扱われます. また, True, False という 2つの値を取る Boolean 型もあります (int 型に変換すると, それぞれ 1 と 0 になります). Python は ==, !=, <, <=, >, >= といった普通の比較操作が使えます. Java, C と異なり, == は文字列に対しても正しく動作するように オーバーロードされています. 真偽値の演算子は *and*, *or*, *not* と書きます (Python は C の書式である && || ! を使いません). 以下は警察官がスピード違反者を捕まえるためのコードのようなものです. then/else に対する命令のひとまとまりは : で始まり, 字下げで まとめられています.
  if speed >= 80:
    print 'License and registration please'
    if mood == 'terrible' or speed >= 100:
      print 'You have the right to remain silent.'
    elif mood == 'bad' or speed >= 90:
      print "I'm going to have to write you a ticket."
      write_ticket()
    else:
      print "Let's try to keep it under 80 ok?"
# coding: utf-8
  if speed >= 80:
    print u'免許証見せて下さい'
    if mood == u'ひどい' or speed >= 100:
      print 'あなたには黙秘権があります.'
    elif mood == u'悪い' or speed >= 90:
      print u"違反切符切りますね."
      write_ticket()
    else:
      print u"80 以下で走って下さい. いいですか?"

上のようなコードを入力するとき, ":" を忘れてしまうのが しばしば私がしてしまう文法の誤りです. これは恐らく C++/Java の習慣に対して余分に入力しなければ いけないものだからでしょう. また, 真偽値の確認を括弧の中に入れないこと. それは C/Java の習慣です. もしコードが短ければ, 次のように ":" の後ろの同じ行にそのコードを書くことができます (これは関数, 繰り返し, などにも当てはまります). しかし, 別々の行に置く方が読みやすいと感じる人たちもいます.
  if speed >= 80: print 'You are so busted'
  else: print 'Have a nice day'
# coding: utf-8
  if speed >= 80: print u'逮捕します'
  else: print u'安全運転をお願いします'

練習問題: string1.py


この節の内容を練習するには, Basic Exercises (英語) ( 基本問題 (日本語訳)) にある string1.py の練習問題に挑戦すること.
この資料は Google の Nick Parlante によって作成されたものの翻訳です. Google による Python の授業の文章と映像は Creative Commons Attribution 2.5 ライセンスの下で利用できます.