Best practices ============== - enumerate - generators - genexps - iteators - with et contextlib enumerate ========= Sous-utilisé ! :: >>> liste = ('un', 'deux', 'trois') >>> for index, val in enumerate(liste): ... print '%d: %s' % (index, val) ... 0: un 1: deux 2: trois Generators ========== - yield est devenu une expression (2.5) :: >>> def foo(): ... answer = (yield) ... while True: ... answer = yield answer + 1 ... >>> gen = foo() >>> gen.next() >>> gen.send(1) 2 >>> gen.send(45) 46 >>> gen.send(89) 90 Generators ========== - possibilité d'écrire des co-routines - extension `multitask` sous PyPI - greenlet (dispo sans les expr. yield) Genexps ======= :: >>> iter = (x**2 for x in range(10) if x % 2 == 0) >>> for el in iter: ... print el ... 0 4 16 36 64 Iterators ========= utilisez itertools : compilé en C - islice - tee - groupby islice ====== - islice, iterator fenêtre :: >>> import itertools >>> def starting_at_five(): ... value = raw_input().strip() ... while value != '': ... for el in itertools.islice(value.split(), ... 4, None): ... yield el ... value = raw_input().strip() ... >>> iter = starting_at_five() >>> iter.next() one two three four five six 'five' >>> iter.next() 'six' >>> iter.next() one two one two three four five six 'five' >>> iter.next() 'six' Tee === - tee: multi-iterator:: >>> import itertools >>> seq = range(1000) >>> def with_head(iterable, headsize=1): ... a, b = itertools.tee(iterable) ... return list(itertools.islice(a, headsize)), b ... >>> with_head(seq) ([1], ) >>> with_head(seq, 4) ([1, 2, 3, 4], ) groupby ======= - semblable à uniq:: >>> from itertools import groupby >>> def compress(data): ... return ((len(list(group)), name) ... for name, group in groupby(data)) ... >>> def decompress(data): ... return (car * size for size, car in data) ... >>> list(compress('get uuuuuuuuuuuuuuuuuup')) [(1, 'g'), (1, 'e'), (1, 't'), (1, ' '), (18, 'u'), (1, 'p')] >>> compressed = compress('get uuuuuuuuuuuuuuuuuup') >>> ''.join(decompress(compressed)) 'get uuuuuuuuuuuuuuuuuup' with et contextlib ================== Introduit dans 2.6 mais dispo dans 2.5 avec __future__. Sans with:: >>> f = open(my_file, 'w') >>> try: ... f.write('pycon fr, ca roxor') ... finally: ... f.close() with et contextlib ================== Avec with:: >>> from __future__ import with_statement >>> with open(my_file, 'w') as f: ... f.write('pycon fr, ca roxor') contextlib ========== Création de ses propres contextes: - implementer __enter__ et __exit__