Я читал о List comprehension без [] в Python, поэтому теперь я знаю, что
''.join([str(x) for x in mylist])
быстрее, чем
''.join(str(x) for x in mylist)
потому что "понимание списков сильно оптимизировано"
Поэтому я полагаю, что оптимизация основана на анализе выражения for
, видит mylist
, вычисляет его длину и использует его для предварительного выделения точного размера массива, что экономит много перераспределения.
При использовании ''.join(str(x) for x in mylist)
, join
получает генератор вслепую и должен строить свой список, не зная заранее размер.
Но теперь рассмотрим это:
mylist = [1,2,5,6,3,4,5]
''.join([str(x) for x in mylist if x < 4])
Как python определяет размер понимания списка? Вычисляется ли он из размера mylist
и сокращается, когда итерации выполняются (что может быть очень плохо, если список большой, а условие отфильтровывает 99% элементов), или оно возвращается обратно к "дону", t знать размер заранее "случае?
EDIT: Я сделал несколько небольших тестов и, похоже, подтвердил, что существует оптимизация:
без условия:
import timeit
print(timeit.timeit("''.join([str(x) for x in [1,5,6,3,5,23,334,23234]])"))
print(timeit.timeit("''.join(str(x) for x in [1,5,6,3,5,23,334,23234])"))
дает (как и ожидалось):
3.11010817019474
3.3457350077491026
с условием:
print(timeit.timeit("''.join([str(x) for x in [1,5,6,3,5,23,334,23234] if x < 50])"))
print(timeit.timeit("''.join(str(x) for x in [1,5,6,3,5,23,334,23234] if x < 50)"))
дает:
2.7942209702566965
3.0316467566203276
поэтому условный listcomp все еще быстрее.