Os outros entrevistados estavam corretos ao responder que você havia descoberto uma expressão geradora (que tem uma notação semelhante às compreensões de lista, mas sem os colchetes ao redor).
Em geral, genexps (como são carinhosamente conhecidos) são mais eficientes em termos de memória e mais rápidas do que as compreensões de listas.
NO ENTANTO, no caso de ''.join()
, a compreensão de uma lista é mais rápida e mais eficiente em termos de memória. O motivo é que a junção precisa fazer duas passagens pelos dados, portanto, na verdade, precisa de uma lista real. Se você der um, ele pode começar seu trabalho imediatamente. Se, em vez disso, você fornecer uma genexp, ela não poderá começar a trabalhar até que crie uma nova lista na memória executando a genexp até a exaustão:
~ $ python -m timeit '"".join(str(n) for n in xrange(1000))'
1000 loops, best of 3: 335 usec per loop
~ $ python -m timeit '"".join([str(n) for n in xrange(1000)])'
1000 loops, best of 3: 288 usec per loop
O mesmo resultado é válido ao comparar itertools.imap versus map :
~ $ python -m timeit -s'from itertools import imap' '"".join(imap(str, xrange(1000)))'
1000 loops, best of 3: 220 usec per loop
~ $ python -m timeit '"".join(map(str, xrange(1000)))'
1000 loops, best of 3: 212 usec per loop
join
provavelmente está escrito em C e, portanto, funciona muito mais rápido do que uma compreensão de lista ... Tempo de teste!