Я играю с пониманием списков и наткнулся на этот небольшой фрагмент на другом сайте:
return ''.join([`num` for num in xrange(loop_count)])
Я потратил несколько минут, пытаясь воспроизвести функцию (печатая), прежде чем понял, что `num`
бит ломает ее.
Что делает заключение в эти символы? Насколько я понимаю, это эквивалент str (num). Но когда я засек:
return ''.join([str(num) for num in xrange(10000000)])
Это занимает 4,09 с, тогда как:
return ''.join([`num` for num in xrange(10000000)])
занимает 2,43 с.
Оба дают одинаковые результаты, но один работает намного медленнее. Что здесь происходит?
РЕДАКТИРОВАТЬ: Как ни странно ... repr()
дает немного более медленные результаты, чем `num`
. 2,99 с против 2,43 с. Использование Python 2.6 (еще не пробовал 3.0).
python
list-comprehension
Доминик Боу-Самра
источник
источник
Ответы:
Обратные кавычки - это устаревший псевдоним для
repr()
. Больше не используйте их, синтаксис был удален в Python 3.0.Использование обратных кавычек кажется быстрее, чем использование
repr(num)
илиnum.__repr__()
в версии 2.x. Я предполагаю, что это потому, что требуется дополнительный поиск в словаре в глобальном пространстве имен (дляrepr
) или в пространстве имен объекта (для__repr__
) соответственно.Использование
dis
модуля подтверждает мое предположение:def f1(a): return repr(a) def f2(a): return a.__repr__() def f3(a): return `a`
Разборка показывает:
>>> import dis >>> dis.dis(f1) 3 0 LOAD_GLOBAL 0 (repr) 3 LOAD_FAST 0 (a) 6 CALL_FUNCTION 1 9 RETURN_VALUE >>> dis.dis(f2) 6 0 LOAD_FAST 0 (a) 3 LOAD_ATTR 0 (__repr__) 6 CALL_FUNCTION 0 9 RETURN_VALUE >>> dis.dis(f3) 9 0 LOAD_FAST 0 (a) 3 UNARY_CONVERT 4 RETURN_VALUE
f1
включает глобальный поискrepr
,f2
поиск атрибутов__repr__
, тогда как оператор обратного апострофа реализован в отдельном коде операции. Поскольку нет накладных расходов ни на поиск по словарю (LOAD_GLOBAL
/LOAD_ATTR
), ни на вызовы функций (CALL_FUNCTION
), обратные кавычки выполняются быстрее.Я предполагаю, что люди Python решили, что иметь отдельную операцию низкого уровня для
repr()
не стоит, а наличие обоихrepr()
и обратных кавычек нарушает принциппоэтому эта функция была удалена в Python 3.0.
источник
Использование обратных кавычек обычно бесполезно и отсутствует в Python 3.
Для чего это стоит:
''.join(map(repr, xrange(10000000)))
для меня немного быстрее, чем версия с обратной кавычкой. Но беспокоиться об этом - вероятно, преждевременная оптимизация.
источник
timeit
дает более быстрые результаты,''.join(map(repr, xrange(0, 1000000)))
чем для''.join([repr(i) for i in xrange(0, 1000000)])
(даже хуже''.join( (repr(i) for i in xrange(0, 1000000)) )
). Это немного разочаровывает ;-)map
реализован в C с использованием цикла C, который намного быстрее, чем цикл Python, выполняемый на виртуальной машине.map
кажется мне совершенно ясным и кратким, а я даже не знаю Python.Я предполагаю, что
num
это не определяет метод__str__()
, поэтомуstr()
необходимо выполнить второй поиск__repr__
.Обратные кавычки ищите напрямую
__repr__
. Если это правда, то использованиеrepr()
вместо обратных кавычек должно дать те же результаты.источник