ฉันจะเพิ่มเนื้อหาของ iterable ให้กับชุดได้อย่างไร?


คำตอบ:


228

คุณสามารถเพิ่มองค์ประกอบของ a listเข้ากับสิ่ง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

3
โปรดทราบว่าการแสดงเป็นเพียงเช่น{1, 2, 3}ในหลาม 3 ในขณะที่มันเป็นset([1, 2, 3])ในหลาม 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วิธีการนี้

การใช้|= set()ต้นทุนประมาณ 1.5 เท่าupdateจะทำอะไรแต่ครึ่งหนึ่งของสิ่งที่เพิ่มแต่ละรายการในลูป


14

คุณสามารถใช้ฟังก์ชั่น set () เพื่อแปลง iterable เป็นชุดแล้วใช้ตัวดำเนินการอัพเดตชุดมาตรฐาน (| =) เพื่อเพิ่มค่าที่ไม่ซ้ำจากชุดใหม่ของคุณเป็นชุดที่มีอยู่

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

5
การใช้.updateมีประโยชน์ที่การโต้แย้งสามารถทำซ้ำได้ - ไม่จำเป็นต้องเป็นชุด - ซึ่งแตกต่างจาก RHS ของ|=ผู้ประกอบการในตัวอย่างของคุณ
tzot

1
จุดดี. เป็นเพียงตัวเลือกสุนทรียะตั้งแต่ set () สามารถแปลง iterable เป็น set แต่จำนวน keystrokes เท่ากัน
gbc

ฉันไม่เคยเห็นโอเปอเรเตอร์นั้นมาก่อนฉันจะสนุกกับการใช้มันเมื่อมันปรากฏขึ้นในอนาคต ขอบคุณ!
eipxen

1
@ eipxen: มี|สหภาพแรงงาน&แยกและ^สำหรับองค์ประกอบที่อยู่ในหนึ่งหรืออื่น ๆ แต่ไม่ใช่ทั้งสอง แต่ในภาษาที่พิมพ์แบบไดนามิกซึ่งบางครั้งก็ยากที่จะอ่านรหัสและรู้ว่าวัตถุชนิดใดที่บินไปมาฉันรู้สึกลังเลที่จะใช้ตัวดำเนินการเหล่านี้ คนที่ไม่รู้จักพวกเขา (หรืออาจไม่รู้ด้วยซ้ำว่า Python อนุญาตให้ตัวดำเนินการเช่นนี้) อาจสับสนและคิดว่าการดำเนินการทางตรรกะหรือบิตตรรกะแปลก ๆ เกิดขึ้น มันจะดีถ้าผู้ประกอบการเหล่านี้ทำงานบน iterables อื่น ๆ เช่นกัน ...
ArtOfWarfare

เรียกใช้การทดสอบบางครั้งกับสิ่งนี้เทียบกับ.update()และเพิ่มแต่ละองค์ประกอบในลูป พบว่า.update()เร็วขึ้น ฉันเพิ่มผลลัพธ์ของฉันลงในคำตอบที่มีอยู่นี้: stackoverflow.com/a/4046249/901641
ArtOfWarfare

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

ใช้รายการความเข้าใจ

ลัดวงจรการสร้าง iterable โดยใช้รายการเช่น :)

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

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

สำหรับบันทึกฉันคิดว่าการยืนยันว่า "ควรมีอย่างใดอย่างหนึ่ง - และดีกว่าเพียงหนึ่ง - วิธีที่ชัดเจนที่จะทำ." เป็นของปลอม มันทำให้มีข้อสันนิษฐานว่าผู้คนที่มีความคิดทางเทคนิคจำนวนมากทำทุกคนคิดเหมือนกัน สิ่งที่ชัดเจนสำหรับคนคนหนึ่งนั้นไม่ชัดเจนสำหรับคนอื่น

ฉันจะยืนยันว่าโซลูชันที่เสนอของฉันนั้นอ่านได้ชัดเจนและทำตามที่คุณขอ ฉันไม่เชื่อว่ามีการแสดงที่เกี่ยวข้องกับการแสดงใด ๆ - แม้ว่าฉันยอมรับว่าฉันอาจจะหายไปบางสิ่งบางอย่าง แต่ถึงอย่างไรก็ตามทั้งหมดนี้อาจไม่ชัดเจนและเป็นที่นิยมของผู้พัฒนารายอื่น


โอ๊ะ! การวนรอบอยู่ในหนึ่งบรรทัดเช่นนั้นกำลังจัดรูปแบบในคำตอบของฉัน - ฉันจะไม่ทำอย่างนั้น เคย.
jaydel

คุณถูกต้องอย่างแน่นอน ฉันแก้ไขโพสต์เพื่อซ่อมแซมความเสียหายของฉัน ขอบคุณ :)
jaydel

9
คุณพลาดจุดที่aset.update(iterable)วนรอบความเร็ว C ในขณะที่for item in iterable: aset.add(item)วนรอบความเร็ว Python ด้วยการค้นหาเมธอดและการเรียกเมธอด (aarrgghh !!) ต่อรายการ
John Machin

1
ขออภัยเขาไม่ได้พูดอะไรเกี่ยวกับการแสดงในคำถามของเขาดังนั้นฉันจึงไม่ต้องกังวล
jaydel
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.