web-dev-qa-db-ja.com

Python:iterableのコンテンツをセットに追加する方法は?

"one [...]明白な方法" とは、既存のsetにイテラブルのすべてのアイテムを追加すること

139
Ian Mackinnon

セットでは、setを意味しますか?

>>> foo = set(range(0, 4))
>>> foo
set([0, 1, 2, 3])
>>> foo.update(range(2, 6))
>>> foo
set([0, 1, 2, 3, 4, 5])

信じる人のためにaset.add()をループで実行すると、aset.update()を実行した場合とパフォーマンスが競合することになります。ここに、公開する前に信念をすばやくテストする方法の例を示します。

>\python27\python -mtimeit -s"it=xrange(10000);a=set(xrange(100))" "a.update(it)"
1000 loops, best of 3: 294 usec per loop

>\python27\python -mtimeit -s"it=xrange(10000);a=set(xrange(100))" "for i in it:a.add(i)"
1000 loops, best of 3: 950 usec per loop

>\python27\python -mtimeit -s"it=xrange(10000);a=set(xrange(100))" "a |= set(it)"
1000 loops, best of 3: 458 usec per loop

>\python27\python -mtimeit -s"it=xrange(20000);a=set(xrange(100))" "a.update(it)"
1000 loops, best of 3: 598 usec per loop

>\python27\python -mtimeit -s"it=xrange(20000);a=set(xrange(100))" "for i in it:a.add(i)"
1000 loops, best of 3: 1.89 msec per loop

>\python27\python -mtimeit -s"it=xrange(20000);a=set(xrange(100))" "a |= set(it)"
1000 loops, best of 3: 891 usec per loop

ループアプローチのアイテムあたりのコストは、updateアプローチの3倍以上のようです。

|= set()を使用すると、updateの約1.5倍の費用がかかりますが、ループに個々のアイテムを追加する場合の半分になります。

34
John Machin

Set()関数を使用してイテラブルをセットに変換し、次に標準セット更新演算子(| =)を使用して、新しいセットから既存のセットに一意の値を追加できます。

>>> a = { 1, 2, 3 }
>>> b = ( 3, 4, 5 )
>>> a |= set(b)
>>> a
set([1, 2, 3, 4, 5])
11
gbc

簡単な更新、python 3を使用したタイミング:

#!/usr/local/bin python3
from timeit import Timer

a = set(range(1, 100000))
b = list(range(50000, 150000))

def one_by_one(s, l):
    for i in l:
        s.add(i)    

def cast_to_list_and_back(s, l):
    s = set(list(s) + l)

def update_set(s,l):
    s.update(l)

結果は次のとおりです。

one_by_one 10.184448844986036
cast_to_list_and_back 7.969255169969983
update_set 2.212590195937082
2
Daniel Dubovski

リストの内包表記を使用

リストを使用して反復可能の作成を短絡する例:)

>>> x = [1, 2, 3, 4]
>>> 
>>> k = x.__iter__()
>>> k
<listiterator object at 0x100517490>
>>> l = [y for y in k]
>>> l
[1, 2, 3, 4]
>>> 
>>> z = Set([1,2])
>>> z.update(l)
>>> z
set([1, 2, 3, 4])
>>> 

[編集:質問の設定部分を逃した]

0
pyfunc