Là gì "một [...] cách rõ ràng" để thêm tất cả các mục của một iterable đến một hiện set
?
Là gì "một [...] cách rõ ràng" để thêm tất cả các mục của một iterable đến một hiện set
?
Câu trả lời:
Bạn có thể thêm các yếu tố của a list
vào set
như thế này:
>>> 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
tạo lấy một lần lặp làm đối số của nó.
{1, 2, 3}
trong Python 3 trong khi đó là set([1, 2, 3])
ở Python 2.
Vì lợi ích của bất kỳ ai có thể tin, ví dụ như thực hiện aset.add()
trong một vòng lặp sẽ có hiệu suất cạnh tranh với việc thực hiện aset.update()
, đây là một ví dụ về cách bạn có thể kiểm tra niềm tin của mình một cách nhanh chóng trước khi công khai:
>\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
Có vẻ như chi phí cho mỗi mục của cách tiếp cận vòng lặp lớn hơn BA lần so với update
cách tiếp cận.
Sử dụng |= set()
chi phí khoảng 1,5 lần những gì update
làm được nhưng một nửa của việc thêm từng mục riêng lẻ vào một vòng lặp.
Bạn có thể sử dụng hàm set () để chuyển đổi một lần lặp thành một tập hợp, sau đó sử dụng toán tử cập nhật tập hợp tiêu chuẩn (| =) để thêm các giá trị duy nhất từ tập hợp mới của bạn vào tập hợp hiện có.
>>> a = { 1, 2, 3 }
>>> b = ( 3, 4, 5 )
>>> a |= set(b)
>>> a
set([1, 2, 3, 4, 5])
.update
có lợi ích là đối số có thể là bất kỳ lặp đi lặp lại nhất thiết phải là một tập hợp không giống như RHS của |=
toán tử trong ví dụ của bạn.
|
kết hợp, &
giao nhau và ^
để có được các yếu tố nằm trong một hoặc khác nhưng không phải cả hai. Nhưng trong một ngôn ngữ được gõ động, đôi khi rất khó đọc mã và biết các loại vật thể bay xung quanh, tôi cảm thấy do dự khi sử dụng các toán tử này. Một số người không nhận ra chúng (hoặc có lẽ thậm chí không nhận ra rằng Python cho phép các toán tử như thế này) có thể bị nhầm lẫn và nghĩ rằng một số hoạt động logic hoặc bit lạ kỳ đang diễn ra. Thật tuyệt nếu các nhà khai thác này cũng làm việc trên các iterables khác ...
.update()
và thêm các yếu tố riêng lẻ trong một vòng lặp. Tìm thấy đó .update()
là nhanh hơn. Tôi đã thêm kết quả của mình vào câu trả lời hiện có này: stackoverflow.com/a/4046249/901641
Chỉ cần cập nhật nhanh, hẹn giờ bằng 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)
kết quả là:
one_by_one 10.184448844986036
cast_to_list_and_back 7.969255169969983
update_set 2.212590195937082
Sử dụng danh sách hiểu.
Đoản mạch việc tạo iterable bằng cách sử dụng một danh sách chẳng hạn :)
>>> 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])
>>>
[Chỉnh sửa: bỏ lỡ phần đặt câu hỏi]
for item in items:
extant_set.add(item)
Đối với hồ sơ, tôi nghĩ rằng khẳng định rằng "Nên có một - và tốt nhất là chỉ có một cách rõ ràng để làm điều đó." là không có thật Nó đưa ra một giả định mà nhiều người có đầu óc kỹ thuật đưa ra, mọi người đều nghĩ giống nhau. Điều gì là hiển nhiên đối với một người không quá rõ ràng đối với người khác.
Tôi sẽ lập luận rằng giải pháp đề xuất của tôi rõ ràng có thể đọc được, và làm những gì bạn yêu cầu. Tôi không tin có bất kỳ bản hit hiệu suất nào liên quan đến nó - mặc dù tôi thừa nhận mình có thể đang thiếu thứ gì đó. Nhưng bất chấp tất cả những điều đó, nó có thể không rõ ràng và thích hợp hơn với một nhà phát triển khác.
aset.update(iterable)
vòng lặp ở tốc độ C trong khi for item in iterable: aset.add(item)
vòng lặp ở tốc độ Python, với tra cứu phương thức và gọi phương thức (aarrgghh !!) cho mỗi mục.