リスト内包表記について
いまさらリスト内包表記かよって言われそうだけど、まぁなんどおさらいしたっていいじゃない。という訳で下記のような事がやりたいとする。
- カンマ区切りの数字の列を文字列として受け取る(50,100,150,200,250)
- その文字列をカンマで分割してリストにする
- リストの各要素をint型にキャストする
- 最終的にリストをtuple型にキャストする
''50,100,150,200,250" ↓変換 (50, 100, 150, 200, 250)
1. ベタにやってみる。
ベタな感じやってみるとこうなる
#!/usr/bin/env python #-*- coding:utf8 -*- num_str = '50,100,150,200,250' num_list = [] for n in num_str.split(','): num_list.append(int(n)) print tuple(num_list) #=> (50, 100, 150, 200, 250)
2. リスト内包表記でやってみる。
上のでも大した行数ではないけど、リスト内包表記を使う事でより簡潔にかける!
#!/usr/bin/env python #-*- coding:utf8 -*- num_str = '50,100,150,200,250' print tuple([int(n) for n in num_str.split(',')]) #=> (50, 100, 150, 200, 250)
3. リスト内包表記の方がパフォーマンスが良い。
エキスパートPythonとか、初めてのPython(オライリー本)にも書いてあったけど、リスト内包表記の方が、往々にしてパフォーマンスが良いとされている。実際に上の二つを比較してみる。
こういう小さいコードの計測する時にはtimeitというモジュールを使うといいらしい。
#!/usr/bin/env python #-*- coding:utf8 -*- import timeit setup = """ num_str = '50,100,150,200,250' def num_str_to_tuple(): num_list = [] for n in num_str.split(','): num_list.append(int(n)) return tuple(num_list) """ stmt = "num_str_to_tuple()" t = timeit.Timer(stmt=stmt, setup=setup) print t.timeit(2000000) setup = """ num_str = '50,100,150,200,250' def num_str_to_tuple(): return tuple([int(n) for n in num_str.split(',')]) """ stmt = "num_str_to_tuple()" t = timeit.Timer(stmt=stmt, setup=setup) print t.timeit(2000000)
リスト内包表記のパフォーマンスがいいからといって今回の例だと、あまりに例がシンプルすぎて差がわかりずらいので、あえて実行回数を多めにしている。
手元の環境で上記計測コードを実行すると。こんな感じ
14.5897488594 #リスト内包表記を使ってない 13.1452250481 #リスト内包表記を使ってる
200まんかいずつ繰り返したら一秒くらいはやくなりますた。
追記(20110916)
よく考えたら、上の計測のヤツは、num_str のカンマで区切られた要素数が、多いほど、差が顕著にでるような気がしたので下記のようにしてみた。
#!/usr/bin/env python #-*- coding:utf8 -*- import timeit setup = """ num_str = ','.join([str(i) for i in range(10000000)]) def num_str_to_tuple(): num_list = [] for n in num_str.split(','): num_list.append(int(n)) return tuple(num_list) """ stmt = "num_str_to_tuple()" t = timeit.Timer(stmt=stmt, setup=setup) print t.timeit(1) setup = """ num_str = ','.join([str(i) for i in range(10000000)]) def num_str_to_tuple(): return tuple([int(n) for n in num_str.split(',')]) """ stmt = "num_str_to_tuple()" t = timeit.Timer(stmt=stmt, setup=setup) print t.timeit(1)
結果はこんな感じ
12.9693031311 #リスト内包表記を使ってない 11.8190917969 #リスト内包表記を使ってる
あんま上の計測のヤツと変わりませんでした。。。
参考
- 作者: Mark Lutz,夏目大
- 出版社/メーカー: オライリージャパン
- 発売日: 2009/02/26
- メディア: 大型本
- 購入: 12人 クリック: 423回
- この商品を含むブログ (133件) を見る
- 作者: Tarek Ziade,稲田直哉,渋川よしき,清水川貴之,森本哲也
- 出版社/メーカー: KADOKAWA/アスキー・メディアワークス
- 発売日: 2010/05/28
- メディア: 大型本
- 購入: 33人 クリック: 791回
- この商品を含むブログ (90件) を見る