it-swarm.com.ru

Наборы Python против списков

В Python, какая структура данных является более эффективной/быстрой? Предполагая, что порядок не важен для меня, и я все равно буду проверять наличие дубликатов, является ли набор Python более медленным, чем список Python?

147
Mantas Vidutis

Это зависит от того, что вы собираетесь с этим делать.

Наборы значительно быстрее, когда дело доходит до определения наличия объекта в наборе (как в x in s), но медленнее, чем списки, когда дело доходит до перебора их содержимого.

Вы можете использовать модуль timeit , чтобы увидеть, что быстрее для вашей ситуации.

182
Michael Aaron Safyan

Списки немного быстрее, чем наборы, когда вы просто хотите перебрать значения.

Наборы, однако, значительно быстрее, чем списки, если вы хотите проверить, содержится ли в них элемент. Они могут содержать только уникальные предметы.

Оказывается, кортежи работают почти так же, как списки, за исключением их неизменности.

Итерация

>>> def iter_test(iterable):
...     for i in iterable:
...         pass
...
>>> from timeit import timeit
>>> timeit(
...     "iter_test(iterable)",
...     setup="from __main__ import iter_test; iterable = set(range(10000))",
...     number=100000)
12.666952133178711
>>> timeit(
...     "iter_test(iterable)",
...     setup="from __main__ import iter_test; iterable = list(range(10000))",
...     number=100000)
9.917098999023438
>>> timeit(
...     "iter_test(iterable)",
...     setup="from __main__ import iter_test; iterable = Tuple(range(10000))",
...     number=100000)
9.865639209747314

Определить, есть ли объект

>>> def in_test(iterable):
...     for i in range(1000):
...         if i in iterable:
...             pass
...
>>> from timeit import timeit
>>> timeit(
...     "in_test(iterable)",
...     setup="from __main__ import in_test; iterable = set(range(1000))",
...     number=10000)
0.5591847896575928
>>> timeit(
...     "in_test(iterable)",
...     setup="from __main__ import in_test; iterable = list(range(1000))",
...     number=10000)
50.18339991569519
>>> timeit(
...     "in_test(iterable)",
...     setup="from __main__ import in_test; iterable = Tuple(range(1000))",
...     number=10000)
51.597304821014404
124
Ellis Percival

Список производительности:

>>> import timeit
>>> timeit.timeit(stmt='10**6 in a', setup='a = range(10**6)', number=100000)
0.008128150348026608

Установить производительность:

>>> timeit.timeit(stmt='10**6 in a', setup='a = set(range(10**6))', number=100000)
0.005674857488571661

Вы можете рассмотреть Кортеж поскольку они похожи на списки, но не могут быть изменены. Они занимают немного меньше памяти и имеют более быстрый доступ. Они не так гибки, но более эффективны, чем списки. Их обычное использование - служить словарными ключами.

Наборы также являются структурами последовательностей, но с двумя отличиями от списков и кортежей. Хотя наборы имеют порядок, этот порядок является произвольным и не контролируется программистом. Второе отличие состоит в том, что элементы в наборе должны быть уникальными.

set по определению. [ питон | вики ]. 

>>> x = set([1, 1, 2, 2, 3, 3])
>>> x
{1, 2, 3}
7
user2601995

Set выигрывает из-за почти мгновенных проверок «содержит»: https://en.wikipedia.org/wiki/Hash_table

Реализация List: обычно массив, низкий уровень, близкий к металлу, подходящий для итерации и произвольного доступа по индексу элемента.

Установка: https://en.wikipedia.org/wiki/Hash_table , он не выполняет итерацию по списку, но находит элемент, вычисляя hash из ключа, поэтому это зависит от характера ключевых элементов и хэш-функции. Подобно тому, что используется для dict. Я подозреваю, что list может быть быстрее, если у вас очень мало элементов (<5), чем больше число элементов, тем лучше set будет выполнять проверку содержимого. Это также быстро для добавления и удаления элементов.

NOTE: Если list уже отсортирован, поиск list может быть довольно быстрым, но в обычных случаях set быстрее и проще для проверок на наличие ошибок.

4
Christophe Roussy

Я бы порекомендовал реализацию Set, где вариант использования ограничен ссылками или поиском существования, и реализацию Tuple, где вариант использования требует от вас выполнения итерации. Список является низкоуровневой реализацией и требует значительных накладных расходов памяти. 

0
Aditya Kumar Roy