Почему метод list set делает список уникальным быстрее, чем метод ключей словаря?

#python #timeit

#python #timeit

Вопрос:

Вот пример пробной версии timeit для того же:

 >>> import timeit
>>> setup = """
... from random import randint
... rand_list = [randint(0,10) for i in range(0,10000)]
... """

>>> timeit.Timer('list(set(rand_list))', setup=setup).repeat(5, 1000)
[0.17256593704223633, 0.17117094993591309, 0.17115998268127441, 0.17191100120544434, 0.17226791381835938]
>>> timeit.Timer('{ x:True for x in rand_list}.keys()', setup=setup).repeat(5, 1000)
[0.4490840435028076, 0.44455599784851074, 0.442918062210083, 0.4430229663848877, 0.44559407234191895]
 

Как вы можете видеть, метод list(set(MY_LIST)) примерно в 2,5 раза быстрее, чем метод dictionary, результат аналогичен для списков меньшего размера или списков большего размера.

Может кто-нибудь, пожалуйста, объяснить, почему это так, т.Е. Разница в функциональности выполнения обоих этих шагов с точки зрения временной сложности?

Ответ №1:

Вы запускаете цикл Python над 10000 элементами во втором тесте, в понимании словаря; именно этот цикл замедляет его.

Вы могли бы попробовать dict.fromkeys() вместо этого:

 dict.fromkeys(rand_list).keys()
 

Это создает словарь из rand_list значений со всеми установленными значениями None .

Теперь это происходит лишь немного медленнее:

 >>> import timeit
>>> from random import randint
>>> rand_list = [randint(0,10) for i in range(0,10000)]
>>> timeit.Timer('list(set(rand_list))', setup='from __main__ import rand_list').repeat(5, 1000)
[0.1437511444091797, 0.13837504386901855, 0.13841795921325684, 0.1395130157470703, 0.1474599838256836]
>>> timeit.Timer('dict.fromkeys(rand_list).keys()', setup='from __main__ import rand_list').repeat(5, 1000)
[0.18216991424560547, 0.17930316925048828, 0.18064308166503906, 0.17971301078796387, 0.17820501327514648]
 

Этого и следовало ожидать; dict() немного больше работы при отслеживании ключей и значений, в отличие от просто ключей в наборе.