Каков «очевидный [...] способ» добавить все элементы итерируемого к существующему set
?
python
set
conventions
iterable
Ян Маккиннон
источник
источник
set
конструктор принимает в качестве аргумента итерацию.{1, 2, 3}
в Python 3, тогда как это былоset([1, 2, 3])
в Python 2.В интересах любого, кто может поверить, например, что выполнение
aset.add()
в цикле будет иметь производительность, конкурентоспособную по сравнению с выполнениемaset.update()
, вот пример того, как вы можете быстро проверить свои убеждения перед публикацией:Похоже, что цена за элемент в циклическом подходе в три раза выше, чем в
update
подходе.Использование
|= set()
стоит примерно в 1,5update
раза больше, чем половина добавления каждого отдельного элемента в цикле.источник
Вы можете использовать функцию set (), чтобы преобразовать итерируемое в набор, а затем использовать стандартный оператор обновления набора (| =), чтобы добавить уникальные значения из вашего нового набора в существующий.
источник
.update
Преимущество использования заключается в том, что аргумент может быть любым итеративным - не обязательно набором - в отличие от RHS|=
оператора в вашем примере.|
для объединения,&
для пересечения и^
для получения элементов, которые находятся в одном или другом, но не в обоих. Но в динамически типизированном языке, где иногда трудно читать код и знать типы объектов, летающих вокруг, я не решаюсь использовать эти операторы. Кто-то, кто их не распознает (или, возможно, даже не понимает, что Python допускает такие операторы), может быть сбит с толку и думать, что происходят какие-то странные побитовые или логические операции. Было бы хорошо, если бы эти операторы работали и на других итерируемых элементах ....update()
и добавил отдельные элементы в цикл. Нашел, что.update()
было быстрее. Я добавил свои результаты в этот существующий ответ: stackoverflow.com/a/4046249/901641Просто быстрое обновление, время использования Python 3:
результаты:
источник
Используйте понимание списка.
Короткое замыкание создания итерируемого с использованием списка, например :)
[Изменить: пропустил заданную часть вопроса]
источник
Для протокола, я думаю, что утверждение «Должен быть один - и желательно только один - очевидный способ сделать это». подделка Предполагается, что многие технические люди думают, что все думают одинаково. То, что очевидно для одного человека, не так очевидно для другого.
Я бы сказал, что предложенное мной решение легко читается и выполняет то, что вы просите. Я не верю, что с этим связаны какие-то проблемы с производительностью, хотя я допускаю, что я что-то упустил. Но, несмотря на все это, это может быть неочевидным и предпочтительным для другого разработчика.
источник
aset.update(iterable)
зацикливается на скорости C, тогда какfor item in iterable: aset.add(item)
зацикливается на скорости Python, с поиском метода и вызовом метода (aarrgghh !!) для каждого элемента.