저는 파이썬 2.3에서 추가된 모듈 중에 개인적으로 가장 좋아하는 모듈을 꼽으라면 단연 itertools 모듈을 꼽겠습니다. itertools 모듈은 C나 Pascal같은 고급 언어들이나 기타 스크립트 언어들 대부분에서 마저도 지저분하게 처리가 되는 for/while/do-while 등의 루프 패턴들을 정말 간단하게 정리해 주는 데 엄청난 효용을 자랑하는데, 예를 들어 파일에서 START로 시작하는 라인부터 읽고 싶다면 옛날 구현에서는 보통:
1 2 3 4 5 6 7 8 9 |
for line in fo: if line.startswith('START'): break else: return # START가 없음 (..line 처리.. START로 시작했으므로..) for line in fo: .. 본 처리... |
그런데 이제, itertools를 쓰면
1 2 |
for line in itertools.dropwhile(lambda x: x.startswith('START'), fo): ... 본처리 ... |
으흐흐흐.. 그 외에 여러개의 이터레이트 가능한 객체들을 연결해서 한꺼번에 처리해주는 chain이나 여러번 재활용하게 해주는 cycle, 일정회수 반복하게 해주는 repeat등 유용한 것이 정말 많습니다. +_+
그런데, 엊그제 귀도가 샤워 중에 groupby라는 새로운 이터레이터 패턴을 만들었는데 요것도 정말 쓸모가 많은 듯 해서 한번 대장금 보면서(;;;) 구현해 보았습니다. (패치는 여기) groupby는 모인모인의 TitleIndex 같은 페이지에서 정말 지겹게도 쓰이는, 인덱스별 분류 패턴을 간소화를 시켜주는데, 보통 이런 짓을 하려면 이렇게 구현하겠죠.. 문자열이 가득 든 소팅된 x 리스트를 첫자를 기준으로 줄을 그으려면
1 2 3 4 5 6 7 8 9 |
group = (None, []) for s in x: if group[0] is not None and group[0] == s[:1]: group[1].append(s) else: print "----" for gm in group[1]: print gm group = (s[:1], [s]) |
구현이야 되지만, 뭘 하려는지 코드만 대충 봐서는 한눈에 들어오지도 않습니다. 흐흐.. 근데 요걸 새로운 groupby 이터레이터를 쓰면 간단하게 되는군요! 꺄아
1 2 3 4 |
for it in itertools.groupby(lambda i: i[:1], x): print "----" for s in it: print s |
뭐하는지도 눈에 보이고 구현도 간단하고.. 정말 좋네요.. +_+
한글 글자들을 초성 기준으로 분류하는 것도 이렇게 간단하게 됩니다.
1 2 3 4 5 6 |
import itertools, hangul s = '가각간곽나냥뇽당당둥돼래릴'.decode('utf-8') for it in itertools.groupby(lambda h:hangul.split(h)[0], s): for c in it: print c.encode('utf-8'), print |
요렇게 하면 결과는
1 2 3 4 5 |
sbtm(perky):~/cvs/itertools% python test.py 가 각 간 곽 나 냥 뇽 당 당 둥 돼 래 릴 |
귀도도 말했듯, 이터레이터와 제너레이터 장난은 정말 코드 간소화에는 엄청난 도움을 주는 듯 합니다. 앞으로도 재미있는 이터레이터가 2.4에 많이 추가되길..
제네레이터와 이터레이터 얘길 읽다 보니 갑자기 옛날에 보다 말았던 ML (ocaml) 공부를 다시 해보고 싶은 욕구가 솟구치는군요. 굳은 머리가 돌아가려나 몰라… ML 이나 haskell 에 대해서 혹시 아시면 비교해 주실 수 있을까요?
뭔가 알듯모를듯-_- 파이썬은 기초중의 기초 좀 공부하다 말아가지고;;; 퍼키님 고수 맞어 ㅠ
아.. 요즘도 코멘트가 비는 버그가 있나보네요;; 찾아보기는 했는데 언제 발생하는지 -.-a;;; 으흑~
음.. 그런데 제가 ml이나 haskell은 몇장보다가 말은 정도라.. 비교할 만한 수준은 못 될것 같네요.. 혹시 아시는 분은 가르침을.. (_ _)
저도 잘은 모르지만 ML이나 Haskell하고 관련이 있나요? 이터레이터야 C++에도 나오는 그거고, 제네레이터는 한 방향으로만 부르는 코루틴이라고 알고 있습니다. 다르게 보면 resumable function이구요, 호출 사이에서 상태가 보존된다는 면만 보면 C의 static variable과도 비슷합니다.
헉 내 코멘트~~~~ >.<
for line in itertools.dropwhile(lambda x: x.startswith(‘START’), fo): 에서 x.startwith 앞에 not 이 붙어야 하지 않을까요? ^^
오오~ 쵝오 쵝오!!! 딱 내 스딸이에요~
우아!!!!!!!!!!!!!
우왕~~ 멋지당~~~ +_+=b
와~ 편하다… 감사해용 ^.^
여…..역시 초고수
제가 원하던 그거에요 -_-;
^___^ 감사감사