イテラブルのコンテンツをセットに追加するにはどうすればよいですか?


回答:


228

次のようlistにaの要素をa に追加できます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])

2
通訳セッションを振り返って実際に試してみましたが、セットの表現に角かっこがあるため、リスト全体がセットの要素として追加されたと思いました。彼らがそのように表現されていることに私はこれまで気づかなかった。
Ian Mackinnon、

7
setコンストラクターは引数として反復可能オブジェクトを使用するため、その表現を使用すると、インタラクティブセッションに直接貼り付けることができます。
Frank Kusters 2013

3
注表現は、単に例えばされていること{1, 2, 3}だったのに対し、Pythonの3でset([1, 2, 3])のPython 2に
ラドンRosborough

40

たとえば、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()すると約1.5倍のコストがかかりupdateますが、ループ内の各アイテムを追加する場合の半分になります。


14

set()関数を使用して反復可能オブジェクトをセットに変換し、次に標準のセット更新演算子(| =)を使用して、新しいセットの一意の値を既存のセットに追加できます。

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

5
使用することに.updateは、|=例の演算子のRHSとは異なり、引数が反復可能(必ずしもセットではない)であるという利点があります。
tzot

1
いい視点ね。set()はイテラブルをセットに変換できるため、見た目の美しさですが、キーストロークの数は同じです。
gbc

このオペレーターは今まで見たことがありません。将来ポップアップ表示されたときに使用することを楽しみます。ありがとう!
eipxen 2011

1
@eipxen:|ユニオン、&交差、および^どちらか一方にあるが両方にはない要素を取得するためのものがあります。しかし、動的に型付けされた言語では、コードを読んだり、飛び回っているオブジェクトのタイプを把握したりすることが難しい場合があるため、これらの演算子を使用することに抵抗があります。それらを認識しない人(またはおそらくPythonがこれらのような演算子を許可していることにさえ気付いていない人)は混乱し、奇妙なビット演算または論理演算が行われていると考えます。これらのオペレーターも他の
イテラブルに

これに対していくつかの時間テストを実行.update()し、ループに個々の要素を追加しました。それ.update()が速かった。結果をこの既存の回答に追加しました:stackoverflow.com/a/4046249/901641
ArtOfWarfare 2015年

4

簡単な更新、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

0

リスト内包表記を使用します。

たとえば、リストを使用してイテラブルの作成を短絡する:)

>>> 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])
>>> 

[編集:質問の一部を逃した]


1
セットが見当たりませんか?何か不足していますか?
Ian Mackinnon、2010年

-2
for item in items:
   extant_set.add(item)

記録として、私は「それを行うには明白な方法が1つ、できれば1つだけあるべきだ」という主張を考えています。偽物です。それは、多くの技術志向の人々が作ること、誰もが同じように考えることを前提としています。ある人にとって明白なことは、別の人にとってはそれほど明白ではありません。

私の提案した解決策は明確に読みやすく、あなたが尋ねたことを実行すると私は主張します。パフォーマンスに影響があるとは思いませんが、何か不足している可能性があります。しかし、それでも、他の開発者にとっては明白でなく好ましい場合もあります。


ああ!forループがそのような1行にあると、私の回答では書式設定されます。ずっと。
ジェイデル

あなたは絶対的に正しいです。投稿を編集して損傷を修復しました。ありがとう:)
ジェイデル

9
アイテムごとにメソッドルックアップとメソッド呼び出し(aarrgghh !!)を使用して、Pythonの速度でループするのaset.update(iterable)に対し、Cの速度でループするポイントがありませんfor item in iterable: aset.add(item)
John Machin、

1
申し訳ありませんが、彼は彼の質問でパフォーマンスについて何も言わなかったので、私はそれについて心配していませんでした。
ジェイデル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.