วิธีเข้าร่วมสองชุดในหนึ่งบรรทัดโดยไม่ใช้“ |”


171

สมมติว่าSและTได้รับมอบหมายชุด โดยไม่ใช้ตัวดำเนินการเข้าร่วม|ฉันจะค้นหาสหภาพของทั้งสองชุดได้อย่างไร ตัวอย่างเช่นนี่ค้นหาจุดตัด:

S = {1, 2, 3, 4}
T = {3, 4, 5, 6}
S_intersect_T = { i for i in S if i in T }

ดังนั้นฉันจะค้นหาการรวมกันของสองชุดในหนึ่งบรรทัดโดย|ไม่ใช้ได้อย่างไร


1
คุณต้องการที่จะรวมกัน? ถ้าใช่คุณสามารถทำ s.union (t)
Ansuman Bebarta

59
ทำไมคุณไม่ใช้|?
Scott Bartell

1
มีเหตุผลทั่วไปที่จะไม่ใช้|?
matanster

5
เหตุผลหนึ่งอาจผ่านการดำเนินการชุดเป็นอาร์กิวเมนต์ฟังก์ชั่น def apply_set_operation(a, b, set_operation)ลองนึกภาพฟังก์ชั่นบางอย่างเช่น: เมื่อเรียกใช้ฟังก์ชันนี้ผมต้องการapply_set_operation(a, b, set.union)ที่จะapply_set_operation(a, b, set.__or__)
BSA

คำตอบ:


309

คุณสามารถใช้วิธีการรวมสำหรับชุด: set.union(other_set)

โปรดทราบว่ามันส่งคืนชุดใหม่นั่นคือไม่ได้แก้ไขตัวเอง


54
อย่างไรก็ตาม|สามารถแก้ไขตัวแปรอินไลน์ได้:set_a |= set_b
jorgenkg

13
@jorgenkg set_a = set_a.union(set_b)เดียวกับ: หากคุณหมายถึง "ในสถานที่" ทั้งสองจะไม่ทำอย่างนั้นทั้งสร้างใหม่set
nuly

3
@jorgenkg มันยังคงสร้างชุดใหม่และแทนที่การอ้างอิง
Alvaro

3
@Alvaro @ เสมอตามการทดสอบอย่างง่าย: a = set((1, 2, 3,)); b = set((1, 3, 4,)); id_a = id(a); a |= b; assert id_a == id(a)@jorgenkg ถูกต้อง - ตัวแปรaถูกแก้ไขแบบอินไลน์ ฉันพลาดอะไรไปรึเปล่า?
johndodo

3
Nope, a = set((1, 2, 3,)); b = set((1, 3, 4,)); c = a; a |= b; assert id(c) == id(a)ดูไม่เหมือนมัน แม้ว่าจะaถูกทำลายไปcก็ไม่เป็นเช่นนั้น นอกจากcนี้ขณะนี้อยู่ในขณะนี้set([1, 2, 3, 4])ดังนั้นความคิดเห็นของ @ jorgenkg ถูกต้อง
johndodo

45

คุณสามารถใช้or_นามแฝง:

>>> from operator import or_
>>> from functools import reduce # python3 required
>>> reduce(or_, [{1, 2, 3, 4}, {3, 4, 5, 6}])
set([1, 2, 3, 4, 5, 6])

9
รักวิธีนี้ใช้งานได้ดีกว่าและสามารถใช้ได้กับ 2 ชุดขึ้นไป
โคลินซู

42

หากคุณพอใจกับการปรับเปลี่ยนชุดดั้งเดิม (ซึ่งคุณอาจต้องการทำในบางกรณี) คุณสามารถใช้set.update():

S.update(T)

ค่าตอบแทนเป็นNoneแต่Sจะมีการปรับปรุงให้เป็นสหภาพของเดิมและST


23

สมมติว่าคุณไม่สามารถใช้s.union(t)ซึ่งเทียบเท่ากับs | tคุณสามารถลอง

>>> from itertools import chain
>>> set(chain(s,t))
set([1, 2, 3, 4, 5, 6])

หรือถ้าคุณต้องการความเข้าใจ

>>> {i for j in (s,t) for i in j}
set([1, 2, 3, 4, 5, 6])

14

หากเข้าร่วมคุณหมายถึงสหภาพลองสิ่งนี้:

set(list(s) + list(t))

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


set (list (s) + list (t)) จะให้ผลลัพธ์เหมือนกันถ้าคุณจะทำการรวมกัน
Ansuman Bebarta

ฉันรู้ แต่ดูเหมือนว่าเขากำลังพยายามหลีกเลี่ยงการใช้ฟังก์ชั่นบิ ธ ในตัวมิฉะนั้นเขาจะใช้เพียง | ผู้ประกอบการ
BenjaminCohen

listและsetถูกสร้างขึ้นในฟังก์ชั่นหลาม
whackamadoodle3000

10

สมมติว่าคุณมี 2 รายการ

 A = [1,2,3,4]
 B = [3,4,5,6]

เพื่อให้คุณสามารถค้นหาAสหภาพBดังต่อไปนี้

 union = set(A).union(set(B))

ถ้าคุณต้องการหาทางแยกและไม่ใช่ทางแยกคุณทำได้ดังนี้

 intersection = set(A).intersection(set(B))
 non_intersection = union - intersection

7

คุณสามารถนำชุดทั้งสองออกเป็นชุดเดียวดังนี้

>>> set_1 = {1, 2, 3, 4}
>>> set_2 = {3, 4, 5, 6}
>>> union = {*set_1, *set_2}
>>> union
{1, 2, 3, 4, 5, 6}

*unpacks ชุด การเปิดออกเป็นที่ที่สามารถทำซ้ำได้ (เช่นชุดหรือรายการ) แทนทุกรายการที่ได้รับ นี่หมายถึงตัวอย่างข้างต้นทำให้ง่ายขึ้น{1, 2, 3, 4, 3, 4, 5, 6}ซึ่งทำให้ง่ายขึ้น{1, 2, 3, 4, 5, 6}เนื่องจากชุดสามารถมีรายการที่ไม่ซ้ำกันได้เท่านั้น


สิ่งที่*ต้องทำในบรรทัด 3
altabq

5

คุณสามารถทำunionหรือเข้าใจรายการง่าย ๆ

[A.add(_) for _ in B]

A จะมีองค์ประกอบทั้งหมดของ B


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