Python Sorting 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 の整列


整列を行う最も簡単な方法は, リストを引数に取り, その要素を整列させたリストを返す sorted(list) 関数を使うことです. 引数に与えたリストは変わりません.
  a = [5, 1, 4, 3]
  print sorted(a)  ## [1, 3, 4, 5]
  print a  ## [5, 1, 4, 3]

sorted() 関数にはリストを渡すのが一般的ですが, 繰り返し処理できる集合であれば何でも入力に取ることが出来ます. 以前説明した list.sort() メソッドでもこれから説明することを行えます. sorted() 関数は sort() に比べて使いやすそうなので, sorted() を使うことを薦めます.
sorted() 関数は任意に与えられる引数を使って特化させることが出来る. sorted() の任意に与えられる引数を, sorted(list, reverse=True) のように reverse=True とすると, リストを逆順に整列します.
  strs = ['aa', 'BB', 'zz', 'CC']
  print sorted(strs)  ## ['BB', 'CC', 'aa', 'zz'] (大文字小文字の違いを考慮)
  print sorted(strs, reverse=True)   ## ['zz', 'aa', 'CC', 'BB']

key= を使った特化した整列


もっと複雑に特化した整列について, sorted() は 比較の前に各要素を変換する "鍵" になる関数を指定する, 任意の引数 "key=" を取ります. 鍵の関数は 1つの値を取って, 1つの値を返し, 返された "代わりの" 値が整列における比較に使われます.
文字列のリストを使った例として, key=len (組み込みの len() 関数) を指定すると, 文字列はその長さを基準に短いものから長いものへと並べられます. この整列では, 代わりに使われる長さの値からなるリストを得るために, len() がそれぞれの文字列に対して呼ばれ, その代わりの値を使った 整列が実行されます.
  strs = ['ccc', 'aaaa', 'd', 'bb']
  print sorted(strs, key=len)  ## ['d', 'bb', 'ccc', 'aaaa']

calling sorted with key=len


別の例として, 鍵となる関数に "str.lower" を指定すると, 大文字と小文字を同じものとして扱う整列を行えます.
  ## "key" argument specifying str.lower function to use for sorting
  print sorted(strs, key=str.lower)  ## ['aa', 'BB', 'CC', 'zz']

また次のように, 鍵となる関数を自分で記述した MyFn 関数にすることが 出来ます.
  ## 文字列の最後の文字で整列させたい, 文字列のリストがあるとする. 
  strs = ['xc', 'zb', 'yd' ,'wa']

  ## 文字列を引数に取り, 最後の文字を返す関数を書く. 
  ## これが鍵の関数になる ( 1つ値を取り, 1つ値を返す).
  def MyFn(s):
    return s[-1]

  ## 最後の文字で整列させるように, key=MyFn を sorted() に渡す. 
  print sorted(strs, key=MyFn)  ## ['wa', 'zb', 'xc', 'yd']

key= による特化した整列を使うときには, 引数が 1つで, 代わりに整列で使われて, 返り値も 1つとなる 関数を必ず使うこと. また, リストから 2つの値を取り, その順序を示すために負/0/正を返す, 昔から使われている 2つの引数を比較する関数を指定するための 任意の引数 "cmp=cmpFn" も sorted() にはあります. 文字列や整数などに対する組み込みの比較関数は cmp(a, b) で, 特化した比較演算子の中で cmp() を呼ぶことがあるでしょう. より新しい 1引数の key= による整列が一般には望ましいでしょう.

sort() メソッド


sorted() とは別に, リストにおける sort() メソッドは list.sort() により 昇順にリストを整列させます. sort() メソッドは指定されたリストそのものを変更して None を返すので, 使い方は次のようになります.
  alist.sort()            ## 正しい
  alist = blist.sort()    ## NO 正しくない, sort() は何も返さない. 

上の例は sort() に関する良くある誤解で, 整列されたリストは返り値になりません. sort() メソッドはリスト上で呼ばれなければならず, 数え上げられる集合に対して何でも使えるわけではありません (しかし, 上の sorted() 関数は何にでも使えます). sort() メソッドは sorted() 関数より昔からあったので, 昔のコードで sort() を見かけることはあるでしょう. sort() メソッドは新しいリストを作る必要がないので, 整列する要素が既にリストにある場合には, 少し速く整列 させられます.

タプル


タプルは要素を固定された数だけまとめたもので, (x, y) 座標などがあります. タプルはリストのようですが, 交換不可能で, 大きさを変更できません (タプルに含まれている要素の 1つが交換可能になり得るので, 厳密には交換不可能ではありません). タプルは Python において "struct" (構造体) のような役割を果たし, 少し論理的で固定された大きさのまとまりの値を渡すのに便利な方法です. 複数の値を返す必要がある関数は, 複数の値からなるタプルを返せば十分です. 例えば 3次元座標のリストが必要なら, Python での自然な表現は, それぞれが大きさ 3の (x, y, z) のまとまりを持っているタプルの リストになるでしょう.
タプルを作るには, 括弧の中にカンマで区切った値を並べるだけです. "空" のタプルは単に, 何も中にない括弧の対になります. タプルの要素の扱いはリストと同じようになっています. len(), [ ], for, in などすべて同じ動作をします.
  tuple = (1, 2, 'hi')
  print len(tuple)  ## 3
  print tuple[2]    ## hi
  tuple[2] = 'bye'  ## NO, タプルは変更できません
  tuple = (1, 2, 'bye')  ## これは動きます

大きさ 1のタプルを作るときは, 唯一の要素の後にカンマをつけること.
  tuple = ('hi',)   ## 大きさ 1のタプル

文法的には不思議ですが, タプルを括弧の中に式を置いた通常の場合と区別するために カンマは必要です. 括弧を省略したときに, Python はカンマを見てタプルだと判断する場合があります.
タプルにそれと同じ大きさの変数名からなるタプルを代入すると, それぞれ対応する値が代入されます. 代入においてタプルが同じ大きさでないなら, エラーが投げられます. この特徴はリストに対しても機能します.
  (x, y, z) = (42, 13, "hike")
  print z  ## hike
  (err_string, err_code) = Foo()  ## Foo() は大きさ 2のタプルを返す. 

リストの内包表記 (任意)


リストの内包表記は, 場合によっては便利な, より高度な機能ですが, 練習問題には必要ではなく, まず学ぶ必要のあることではありません (つまり, この節は飛ばして構いません). リストの内包表記はリスト全体に展開する式を書く簡潔な方法です. リスト num = [1, 2, 3] (訳注: 以下の擬似コードでは [1, 2, 3, 4]) があるとし, その二乗のリストを計算するリストの内包表現を次に示します.
  nums = [1, 2, 3, 4]

  squares = [ n * n for n in nums ]   ## [1, 4, 9, 16]

書式は [ expr for var in list ] です. ここで for var in list は通常の for による繰り返し処理 に見えますが, コロン (:) がありません. その左にある expr は 新しいリストの値を求めるために, それぞれの要素に対して 1度評価されます. 次は文字列に対する例で それぞれの文字列は '!!!' が付けられた大文字に変更されます.

  strs = ['hello', 'and', 'goodbye']

  shouting = [ s.upper() + '!!!' for s in strs ]
  ## ['HELLO!!!', 'AND!!!', 'GOODBYE!!!']

結果を絞り込むために, for による繰り返しの右側に if による確認を加えることが出来ます. if による確認はそれぞれの要素に対して評価され, その確認が真だった要素だけが結果に含まれます.
  ## 2 以下の値を選ぶ. 
  nums = [2, 8, 1, 6]
  small = [ n for n in nums if n <= 2 ]  ## [2, 1]

  ## 'a' を含む果物を選び, 大文字に変更する. 
  fruits = ['apple', 'cherry', 'bannana', 'lemon']
  afruits = [ s.upper() for s in fruits if 'a' in s ]
  ## ['APPLE', 'BANNANA']

練習問題: list1.py


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