エキスパートPythonプログラミング読書会02に参加しました
エキスパートPythonプログラミング読書会02 : ATND に参加して講師のお手伝いをしてきました。
今回の読書会でお話できたのは第2章のうち以下の内容だけでした。
- リスト内包表記
- イテレータとジェネレータ
- ジェネレータ
- コルーチン
- ジェネレータ式
準備不足で要領よく進行できず、すみませんでした。実際にやってみた雰囲気や進め方など、次回への改善に繋げていきます。2章全般の資料を読書会の前にアップロードして公開していますが、次回まで時間があるので後半部分は修正すると思います。2章全般の内容で、
この内容を詳細に知りたい!
この内容がよく分からなかった(> <)
などなど、何かしらありましたら Twitter で @t2y か、ハッシュタグ #expertpython を付けてコメントください。
スライド資料、サンプルコードは
2010/9/29(水) に少し修正しました。
読書会で使用したサンプルコードです。
- 01
- リスト内包表記の使用例とデータ変換
def same_value_tuple_with_list_comprehension(seqs): """ >>> same_value_tuple_with_list_comprehension(range(3)) [(0, False), (1, False), (2, False)] """ return [(i, False) for i in seqs] def convert_tuple_to_dict(seqs): """ >>> convert_tuple_to_dict(range(3)) {0: False, 1: False, 2: False} """ return dict(same_value_tuple_with_list_comprehension(seqs)) def convert_list_to_json(seqs): """ >>> convert_list_to_json(range(3)) '[[0, false], [1, false], [2, false]]' """ import json return json.dumps(same_value_tuple_with_list_comprehension(seqs)) def convert_dict_to_json(seqs): """ >>> convert_dict_to_json(range(3)) '{"0": false, "1": false, "2": false}' """ import json return json.dumps(convert_tuple_to_dict(seqs)) def list_comprehension_usecase(): """ >>> list_comprehension_usecase() '[{"last_login": "2010-09-05 18:30:45", "name": "user1"}, {"last_login": "2010-09-07 13:55:10", "name": "user2"}]' """ import json from datetime import datetime class TestObj(object): def __init__(self, id, last_login): self.id = id self.last_login = last_login from_conversion_table = { 1: "user1", 2: "user2", } from_or_mapper = [ TestObj(1, datetime(2010, 9, 5, 18, 30, 45)), TestObj(2, datetime(2010, 9, 7, 13, 55, 10)), ] data = [dict( name = from_conversion_table.get(obj.id), last_login = obj.last_login.strftime('%Y-%m-%d %H:%M:%S'), ) for obj in from_or_mapper] # data = [] # for obj in from_or_mapper: # name = from_conversion_table.get(obj.id) # last_login = obj.last_login.strftime('%Y-%m-%d %H:%M:%S') # data.append(dict(name=name, last_login=last_login)) return json.dumps(data)
- 02
- enumerate() の使用例
def read_enumerate(path): """ >>> read_enumerate("./tests/dmesg.log") 642 """ # ファイルの行数を数える処理にも応用できる cnt = -1 for cnt, line in enumerate(open(path, "rb")): pass cnt += 1 return cnt
- 03
- 関数をジェネレータに変更
def toggle(obj): """ >>> g = toggle(True) >>> next(g) False >>> next(g) True >>> next(g) False """ while True: obj = not obj yield obj def search_file_normal(path, file): """ >>> search_file_normal('./tests', '*.txt') ['./tests/abc.txt', './tests/def.txt'] """ import os import glob from os.path import join found = [] for root, dirs, files in os.walk(path): for match in glob.glob(join(root, file)): found.append(match) return found def search_file_gen(path, file): """ >>> [f for f in search_file_gen("./tests", "*.txt")] ['./tests/abc.txt', './tests/def.txt'] >>> g = search_file_gen("./tests", "*.txt") >>> next(g) './tests/abc.txt' >>> next(g) './tests/def.txt' >>> next(g) Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration """ import os import glob from os.path import join for root, dirs, files in os.walk(path): for match in glob.glob(join(root, file)): yield match
- 04
- 任意のディレクトリ配下のサイズとファイル数を調べる
def get_files_and_size_normal(origin_dir): """ >>> get_files_and_size_normal("./test") (3, 12L) """ import os from os.path import getsize, join file_num, size = 0, 0 for root, dirs, files in os.walk(origin_dir): size += sum(getsize(join(root, name)) for name in files) file_num += len(files) return file_num, size def get_files_and_size_gen(origin_dir): """ >>> g = get_files_and_size_gen("./test") >>> next(g) (1, 4L) >>> next(g) (2, 8L) >>> for file_num, size in get_files_and_size_gen("./test"): ... print file_num, size 1 4 2 8 3 12 """ import os from os.path import getsize, join file_num, size = 0, 0 for root, dirs, files in os.walk(origin_dir): size += sum(getsize(join(root, name)) for name in files) file_num += len(files) yield file_num, size
- 05
- ジェネレータの使用例
def read_file_normal(path, mode): """ >>> read_file_normal("./test/test.txt", "r") abc <BLANKLINE> <BLANKLINE> <BLANKLINE> def <BLANKLINE> #comment <BLANKLINE> ghi <BLANKLINE> """ for line in file(path, mode): print line # something to do def read_file_without_linebreak(path, mode, charset="utf-8"): """ >>> for line in read_file_without_linebreak("./test/test.txt", "r"): ... print line abc <BLANKLINE> def #comment ghi """ import io with io.open(path, mode=mode, encoding=charset) as file_obj: for line in file_obj: yield line.rstrip("\r\n") def read_file_without_comment(path, mode, charset="utf-8"): """ >>> for line in read_file_without_comment("./test/test.txt", "r"): ... print line abc def ghi """ import io with io.open(path, mode=mode, encoding=charset) as file_obj: for line in file_obj: if ''.join(line.split()) and not line.startswith("#"): yield line.rstrip("\r\n") def pattern_matching(path, mode): """ >>> for match in pattern_matching("./test/test.txt", "r"): ... print match ab gh """ import re regexp = re.compile("ab|gh") for line in read_file_without_comment(path, mode): for match in regexp.findall(line): yield match
- 06
- send メソッドを使用してジェネレータへ値を渡す簡単な例
def echo_upper(): """ >>> g = echo_upper() >>> next(g) >>> for i in "abc": ... g.send(i) A B C >>> >>> g = echo_upper() >>> for i in [None, "a", "b", "c"]: ... g.send(i) A B C """ while True: data = yield print data.upper()
-
- 値を生成する yield と式の右辺になる yield の2つが出てくる例
def echo_upper_with_2yields(): """ >>> g = echo_upper_with_2yields() >>> for i in "abc": ... next(g) ... print g.send(i) A B C >>> >>> g = echo_upper_with_2yields() >>> for i in [None, "a", None, "b", None, "c"]: ... print g.send(i) None A None B None C """ while True: data = yield yield data.upper() def echo_upper_with_2roles(): """ >>> g = echo_upper_with_2roles() >>> for i in [None, "a", "b", "c"]: ... print g.send(i) INITIAL A B C """ data = "initial" while True: data = yield data.upper()
-
- yield でユーザ認証を作ってみた(動作確認用サンプルであり、実用的ではありません)
def authenticate_simple(): from getpass import getpass secret_table = { "t2y": "secret", } user = yield raw_input("Enter username: ") while True: passwd = yield getpass("passwd: ") if secret_table.get(user) == passwd: return def main(): g = authenticate_simple() r = None try: while True: r = g.send(r) except StopIteration: pass print "Authenticated" if __name__ == "__main__": main()
- 作者: Tarek Ziade,稲田直哉,渋川よしき,清水川貴之,森本哲也
- 出版社/メーカー: アスキー・メディアワークス
- 発売日: 2010/05/28
- メディア: 大型本
- 購入: 33人 クリック: 791回
- この商品を含むブログ (91件) を見る