Apa "satu [...] cara yang jelas" untuk menambahkan semua item dari iterable ke yang sudah ada set
?
Apa "satu [...] cara yang jelas" untuk menambahkan semua item dari iterable ke yang sudah ada set
?
Jawaban:
Anda dapat menambahkan elemen a list
ke set
seperti ini:
>>> foo = set(range(0, 4))
>>> foo
set([0, 1, 2, 3])
>>> foo.update(range(2, 6))
>>> foo
set([0, 1, 2, 3, 4, 5])
set
konstruktor mengambil iterable sebagai argumennya.
{1, 2, 3}
dalam Python 3 sedangkan itu set([1, 2, 3])
dalam Python 2.
Untuk kepentingan siapa pun yang mungkin percaya misalnya bahwa melakukan aset.add()
dalam satu lingkaran akan memiliki kinerja yang kompetitif dengan melakukan aset.update()
, berikut adalah contoh bagaimana Anda dapat menguji keyakinan Anda dengan cepat sebelum go public:
>\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
Sepertinya biaya per item dari pendekatan loop lebih dari TIGA kali lipat dari update
pendekatan.
Menggunakan |= set()
biaya sekitar 1,5x apa yang update
dilakukan tetapi setengah dari apa yang ditambahkan setiap item dalam satu lingkaran tidak.
Anda dapat menggunakan fungsi set () untuk mengubah iterable menjadi set, dan kemudian menggunakan operator pembaruan set standar (| =) untuk menambahkan nilai unik dari set baru Anda ke yang sudah ada.
>>> a = { 1, 2, 3 }
>>> b = ( 3, 4, 5 )
>>> a |= set(b)
>>> a
set([1, 2, 3, 4, 5])
.update
memiliki manfaat bahwa argumennya dapat diubah-ubah — tidak harus merupakan himpunan — tidak seperti RHS |=
operator dalam contoh Anda.
|
untuk persatuan, &
untuk persimpangan, dan ^
untuk mendapatkan elemen yang ada di satu atau yang lain tetapi tidak keduanya. Tetapi dalam bahasa yang diketik secara dinamis di mana kadang-kadang sulit untuk membaca kode dan mengetahui jenis benda yang terbang di sekitar, saya merasa ragu untuk menggunakan operator ini. Seseorang yang tidak mengenalinya (atau mungkin bahkan tidak menyadari bahwa Python memungkinkan untuk operator seperti ini) dapat bingung dan berpikir beberapa operasi aneh bitwise atau logis sedang terjadi. Akan lebih baik jika operator ini bekerja pada iterables lainnya juga ...
.update()
dan menambahkan elemen individual dalam satu lingkaran. Menemukan .update()
itu lebih cepat. Saya menambahkan hasil saya ke jawaban yang ada ini: stackoverflow.com/a/4046249/901641
Hanya pembaruan cepat, timing menggunakan 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)
hasilnya adalah:
one_by_one 10.184448844986036
cast_to_list_and_back 7.969255169969983
update_set 2.212590195937082
Gunakan pemahaman daftar.
Hubungan pendek pembuatan iterable menggunakan daftar misalnya :)
>>> 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])
>>>
[Sunting: merindukan bagian set pertanyaan]
for item in items:
extant_set.add(item)
Sebagai catatan, saya pikir pernyataan bahwa "Harus ada satu - dan lebih disukai hanya satu - cara yang jelas untuk melakukannya." adalah palsu. Itu membuat asumsi bahwa banyak orang berpikiran teknis membuat, bahwa semua orang berpikir sama. Apa yang jelas bagi satu orang tidak begitu jelas bagi orang lain.
Saya berpendapat bahwa solusi yang saya usulkan jelas dapat dibaca, dan melakukan apa yang Anda minta. Saya tidak percaya ada hit kinerja yang terlibat dengannya - meskipun saya akui saya mungkin kehilangan sesuatu. Namun terlepas dari semua itu, mungkin tidak jelas dan lebih disukai daripada pengembang lain.
aset.update(iterable)
loop pada kecepatan C sedangkan for item in iterable: aset.add(item)
loop pada kecepatan Python, dengan pencarian metode dan pemanggilan metode (aarrgghh !!) per item.