Как извлечь член из однопользовательского набора в python?
Недавно я столкнулся с сценарием, в котором, если набор содержит только один элемент, я хотел что-то сделать с этим элементом. Чтобы получить элемент, я решил использовать этот подход:
element = list(myset)[0]
Но это не очень удовлетворительно, поскольку он создает ненужный список. Это также можно сделать с помощью итерации, но итерация кажется неестественной, так как существует только один элемент. Я пропустил что-то простое?
Ответы
Ответ 1
распаковки файлов.
(element,) = myset
(Кстати, python-dev исследовал, но отклонил добавление myset.get(), чтобы вернуть произвольный элемент из набора. Обсуждение здесь, Guido van Rossum отвечает 1 и 2.)
Мой личный фаворит для получения произвольного элемента (когда у вас есть неизвестный номер, но также работает, если у вас есть только один):
element = next(iter(myset)) ¹
1: в Python 2.5 и раньше вам нужно использовать iter(myset).next()
Ответ 2
Между созданием кортежа и созданием итератора это почти стирка, но итерация побеждает носом...:
$ python2.6 -mtimeit -s'x=set([1])' 'a=tuple(x)[0]'
1000000 loops, best of 3: 0.465 usec per loop
$ python2.6 -mtimeit -s'x=set([1])' 'a=tuple(x)[0]'
1000000 loops, best of 3: 0.465 usec per loop
$ python2.6 -mtimeit -s'x=set([1])' 'a=next(iter(x))'
1000000 loops, best of 3: 0.456 usec per loop
$ python2.6 -mtimeit -s'x=set([1])' 'a=next(iter(x))'
1000000 loops, best of 3: 0.456 usec per loop
Не уверен, почему все ответы используют более старый синтаксис iter(x).next()
, а не новый next(iter(x))
, который кажется мне предпочтительным (а также работает в Python 3.1).
Однако распаковка выигрывает с обеих сторон:
$ python2.6 -mtimeit -s'x=set([1])' 'a,=x'
10000000 loops, best of 3: 0.174 usec per loop
$ python2.6 -mtimeit -s'x=set([1])' 'a,=x'
10000000 loops, best of 3: 0.174 usec per loop
Это, конечно, для наборов с одним элементом (где последняя форма, как упоминалось выше, имеет преимущество быстрого простоя, если набор, который вы "знали", имел только один элемент, на самом деле имел несколько). Для множеств с произвольными N > 1 элементами кортеж замедляется, итератор не выполняет:
$ python2.6 -mtimeit -s'x=set(range(99))' 'a=next(iter(x))'
1000000 loops, best of 3: 0.417 usec per loop
$ python2.6 -mtimeit -s'x=set(range(99))' 'a=tuple(x)[0]'
100000 loops, best of 3: 3.12 usec per loop
Итак, распаковка для одноэлементного случая и next(iter(x))
для общего случая кажутся лучшими.
Ответ 3
Я считаю ответ kaizer.se отличным. Но если ваш набор может содержать более одного элемента, и вы хотите не-произвольный элемент, вы можете использовать min
или max
. Например:.
element = min(myset)
или
element = max(myset)
(Не используйте sorted
, потому что у этого нет лишних накладных расходов для этого использования.)
Ответ 4
вы можете использовать element = tuple(myset)[0]
, который немного эффективнее, или вы можете сделать что-то вроде
element = iter(myset).next()
Я предполагаю, что построение итератора более эффективно, чем создание кортежа/списка.
Ответ 5
Я предлагаю:
element = myset.pop()