Guido가 몇 년째 열심히 반대하다가 얼마전에 드디어 들어간 list.sorted와 얼마전 블로그에서 얘기했던 itertools.groupby에서 아주 유용한 itemgetter와 attrgetter가 얼마전에 추가됐습니다. 원래 lambda로 처리해야하는 건데 아무래도 lambda만 들어가면 일단 거부감이 들기 때매.. 흐흐…
예를 들면 원래 [(10, “merong”), (20, “hoho”), (30, “abcd”)]를 순서대로 정렬하려면
1 2 3 4 |
>>> x = [(10, "merong"), (20, "hoho"), (30, "abcd")] >>> x.sort(lambda x,y: cmp(x[1],y[1])) >>> x [(30, 'abcd'), (20, 'hoho'), (10, 'merong')] |
이렇게 됐는데, 파이썬 2.4에서는 이렇게 처리하면 됩니다. (미리 from operator import itemgetter 한 상태)
1 2 |
>>> list.sorted([(10, "merong"), (20, "hoho"), (30, "abcd")], key=itemgetter(1)) [(30, 'abcd'), (20, 'hoho'), (10, 'merong')] |
므흐흐.. 좋기는 한데, 뭔가 itemgetter랑 attrgetter는 너무 한군데만 특수화되었다는 느낌을 지울 수 없는데, 다시 메일링 리스트에 Michael W. Hudson이 엄청난 팁을 하나 공개했는데, 요렇게 쓴다고 합니다. (정확히는 이 코드는 Thomas Heller가 mwh의 사용법을 보고 추리해서 짠 것..)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class Adder: def __init__(self, number): self._number = number def __call__(self, arg): return arg + self._number class X: def __add__(self, number): return Adder(number) X = X() print map(X + 1, range(2)) |
즉, X + 1 하면 + 1하는 순간에 Adder인스턴스가 생성돼서, +1하는 객체로 둔갑을 해서 결국 웬만한 것은 lambda 없이도 쓸 수 있게 된다는.. 크크 정말 멋지네요 +_+. 그런데, 이 방법에서는 X.split(‘.’) 같이 아래 어트리뷰트를 호출하는 건 코드가 실행되는 때가 먼저 와 버리기 때문에 제대로 동작하지 못하게 되는데, 몇가지 껍데기를 씌우면 되기는 되겠네요..
음.. 하여간 대부분의 경우에 정말 멋지게 동작해서 mwh의 이 아이디어는 아주 멋져보입니다.~
(덧붙임: 나중에 리스트에 다른 사람이 이걸 파이썬으로 구현한 소스를 올려놨네요. http://www.sil-tec.gr/~tzot/predicates.py 에서 받을 수 있습니다.)