เพิ่มรายการที่จะตั้ง?


242

ทดสอบกับล่าม Python 2.6:

>>> a=set('abcde')
>>> a
set(['a', 'c', 'b', 'e', 'd'])
>>> l=['f','g']
>>> l
['f', 'g']
>>> a.add(l)
Traceback (most recent call last):
  File "<pyshell#35>", line 1, in <module>
    a.add(l)
TypeError: list objects are unhashable

ฉันคิดว่าฉันไม่สามารถเพิ่มรายการลงในชุดเพราะไม่มีทางที่ Python จะบอกได้ถ้าฉันได้เพิ่มรายการเดิมสองครั้ง มีวิธีแก้ปัญหาหรือไม่?

แก้ไข: ฉันต้องการเพิ่มรายการเองไม่ใช่องค์ประกอบ


2
คุณต้องการเพิ่มรายการในชุดหรือรายการในรายการหรือไม่?
pkit

รายการตัวเอง - ฉันต้องการมีชุดของรายการ
Adam Matan

ดูเหมือนว่าคำตอบที่เหมาะสมที่สุดคือคำที่มีการประเมินต่ำเกินไปแนะนำให้ใช้ aSet.add (id (lst)) ก่อนที่จะเพิ่ม lst ลงในรายการ / คิว / etc เพื่อให้แน่ใจว่าคุณได้ทำแล้ว คุณควรพิจารณาคำตอบที่ได้รับการยอมรับอีกครั้ง
Rustam A.

คำตอบ:


187

คุณไม่สามารถเพิ่มรายการลงในชุดเพราะรายการไม่แน่นอนหมายความว่าคุณสามารถเปลี่ยนเนื้อหาของรายการหลังจากเพิ่มลงในชุด

อย่างไรก็ตามคุณสามารถเพิ่มสิ่งอันดับลงในชุดได้เนื่องจากคุณไม่สามารถเปลี่ยนเนื้อหาของสิ่งอันดับได้:

>>> a.add(('f', 'g'))
>>> print a
set(['a', 'c', 'b', 'e', 'd', ('f', 'g')])

แก้ไข : คำอธิบายบางอย่าง: เอกสารกำหนดsetเป็นคอลเลกชัน unordered ของวัตถุที่แตกต่าง hashable วัตถุจะต้องถูกแฮชเพื่อให้การค้นหาการเพิ่มและการลบองค์ประกอบสามารถทำได้เร็วกว่าการดูที่แต่ละองค์ประกอบทุกครั้งที่คุณทำการดำเนินการเหล่านี้ อัลกอริทึมที่ใช้เฉพาะมีการอธิบายในบทความวิกิพีเดีย อัลกอริทึมการแฮช Pythons ถูกอธิบายไว้ในฟังก์ชัน effbot.orgและ pythons __hash__ในการอ้างอิงของไพธ อน

ข้อเท็จจริงบางอย่าง:

  • ตั้งค่าองค์ประกอบเช่นเดียวกับปุ่มพจนานุกรมจะต้อง hashable
  • บางประเภทข้อมูล unhashable:
    • list: ใช้tupleแทน
    • set: ใช้frozensetแทน
    • dict: ไม่มีคู่อย่างเป็นทางการ แต่มีสูตรบางอย่าง
  • อินสแตนซ์ของวัตถุนั้นแฮชโดยค่าเริ่มต้นโดยแต่ละอินสแตนซ์มีแฮชที่ไม่ซ้ำ คุณสามารถแทนที่พฤติกรรมนี้ได้ตามที่อธิบายไว้ในการอ้างอิงหลาม

6
และถ้าคุณต้องการเพิ่มชุดลงในชุดให้ใช้ frozenet
FogleBird

4
collections.namedtupleอาจได้รับการพิจารณา "ข้าราชการ" dictคู่ของ
SilentGhost

1
@ Wahnfrieden: นั่นคือการเพิ่มเนื้อหาของชุดไม่ใช่ชุดตัวเอง
Otto Allmendinger

@aehlke: ไม่ที่เพิ่มองค์ประกอบของชุดลงในชุดแรก แต่เรากำลังพูดถึงการเพิ่มชุดเป็นองค์ประกอบของชุดแรก
Jeff Learman

578

ใช้set.update()หรือ|=

>>> a = set('abc')
>>> l = ['d', 'e']
>>> a.update(l)
>>> a
{'e', 'b', 'c', 'd', 'a'}

>>> l = ['f', 'g']
>>> a |= set(l)
>>> a
{'e', 'b', 'f', 'c', 'd', 'g', 'a'}

แก้ไข: ถ้าคุณต้องการเพิ่มรายชื่อและไม่ใช่สมาชิกคุณต้องใช้สิ่งอันดับ แต่น่าเสียดาย สมาชิกชุดจะต้องhashable


set.update () เพิ่มรายการในชุดถูกต้องหรือไม่ ไปป์เท่ากับตัวดำเนินการอะไร
FistOfFury

ด้วยความเคารพต่อชุดคือ|ผู้ประกอบการดำเนินการการดำเนินงานชุดยูเนี่ยน ทั้ง|=ผู้ปฏิบัติงานและset.update()วิธีการใช้การดำเนินการนั้นในสถานที่และมีความหมายเหมือนกันได้อย่างมีประสิทธิภาพ ดังนั้นset_a |= set_bอาจพิจารณาน้ำตาลเชิงซ้อนสำหรับทั้งสองset_a.update(set_b) และ set_a = set_a | set_b (ยกเว้นว่าในกรณีหลังset_aวัตถุเดียวกันจะถูกนำกลับมาใช้ซ้ำแทนที่จะกำหนดใหม่) </ahem>
เซซิลแกงกะหรี่

76

ในการเพิ่มองค์ประกอบของรายการลงในชุดให้ใช้update

จากhttps://docs.python.org/2/library/sets.html

s.update (t): ส่งคืนชุด s พร้อมองค์ประกอบที่เพิ่มจาก t

เช่น

>>> s = set([1, 2])
>>> l = [3, 4]
>>> s.update(l)
>>> s
{1, 2, 3, 4}

หากคุณต้องการเพิ่มทั้งรายการเป็นองค์ประกอบเดียวในชุดคุณไม่สามารถทำได้เพราะรายการนั้นไม่แฮช คุณแทนสามารถเพิ่ม tuple s.add(tuple(l))e กรัม ดูเพิ่มเติมที่TypeError: unhashable type: 'list' เมื่อใช้ฟังก์ชั่น set-inเพื่อรับข้อมูลเพิ่มเติม


40

หวังว่านี่จะช่วย:

>>> seta = set('1234')
>>> listb = ['a','b','c']
>>> seta.union(listb)
set(['a', 'c', 'b', '1', '3', '2', '4'])
>>> seta
set(['1', '3', '2', '4'])
>>> seta = seta.union(listb)
>>> seta
set(['a', 'c', 'b', '1', '3', '2', '4'])

15

set.update()กรุณาแจ้งให้ทราบฟังก์ชั่น เอกสารบอกว่า:

อัปเดตชุดกับสหภาพของตัวเองและคนอื่น ๆ


5
นี่ไม่ได้ตอบคำถาม (เนื่องจาก OP ต้องการเพิ่มรายการเองลงในชุด) แต่มันเป็นคำตอบที่ฉันต้องการเมื่อ Google นำมาให้ฉันที่นี่ :-)
tom stratton

1
ดูเหมือนว่าคำตอบที่ตรงประเด็นที่สุดสำหรับฉัน ... ตัวอย่างเช่นถ้า b = set ([1]), b.update ([7,25]) จะให้ค่า b ต่อไปนี้: set ([ 1, 25, 7]) ---> มันไม่ใช่สิ่งที่เรากำลังมองหาที่นี่หรือ
Louis LC

8

วัตถุรายการมี unhashable คุณอาจต้องการเปลี่ยนพวกมันให้เป็นสิ่งอันดับ


5

ชุดไม่สามารถมีองค์ประกอบ / สมาชิกเปลี่ยนแปลงได้ (อาจมีการเปลี่ยนแปลง) รายการที่ไม่แน่นอนไม่สามารถเป็นสมาชิกของชุดได้

เนื่องจากเซตเปลี่ยนแปลงไม่ได้คุณไม่สามารถมีเซตได้! คุณสามารถมีชุดของโหลที่แม้ว่า

("ความต้องการความไม่แน่นอน" ประเภทเดียวกันนี้ใช้กับปุ่มของ dict)

คำตอบอื่น ๆ ได้ให้รหัสแก่คุณแล้วฉันหวังว่านี่จะช่วยให้คุณมีความเข้าใจลึกซึ้ง ฉันหวังว่า Alex Martelli จะตอบคำถามโดยละเอียดมากกว่านี้


4

คุณต้องการเพิ่มสิ่งอันดับไม่ใช่รายการ:

>>> a=set('abcde')
>>> a
set(['a', 'c', 'b', 'e', 'd'])
>>> l=['f','g']
>>> l
['f', 'g']
>>> t = tuple(l)
>>> t
('f', 'g')
>>> a.add(t)
>>> a
set(['a', 'c', 'b', 'e', 'd', ('f', 'g')])

หากคุณมีรายการคุณสามารถแปลงเป็น tuple ดังที่แสดงไว้ด้านบน tuple นั้นไม่เปลี่ยนรูปดังนั้นสามารถเพิ่มเข้าไปในเซตได้


4

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

อย่างไรก็ตามพฤติกรรมที่ฉันต้องการก็คือสำหรับการตั้งค่าการใช้งานมากกว่าid hashฉันพบเช่นนี้mydict[id(mylist)] = mylistแทนที่จะmyset.add(mylist)เสนอพฤติกรรมที่ฉันต้องการ


3

คุณจะต้องการใช้สิ่งอันดับซึ่งเป็น hashable (คุณไม่สามารถแฮชวัตถุที่ไม่แน่นอนเช่นรายการ)

>>> a = set("abcde")
>>> a
set(['a', 'c', 'b', 'e', 'd'])
>>> t = ('f', 'g')
>>> a.add(t)
>>> a
set(['a', 'c', 'b', 'e', 'd', ('f', 'g')])

2

นี่คือวิธีที่ฉันมักจะทำ:

def add_list_to_set(my_list, my_set):
    [my_set.add(each) for each in my_list]
return my_set

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