| = (ior) ทำอะไรใน Python?


114

Google ไม่ยอมให้ฉันค้นหา|=ดังนั้นฉันจึงมีปัญหาในการค้นหาเอกสารที่เกี่ยวข้อง มีใครรู้บ้าง?


5
ฉันคิดว่ามันเกี่ยวข้องที่จะชี้ให้เห็นดังคำตอบของซันนี่ด้านล่างซึ่ง|ใช้เป็นตัวดำเนินการตั้งค่าสหภาพด้วย
TallChuck

10
ในปี 2019 Google จะให้คุณค้นหา `| =`! :-)
rbennell

คำตอบ:


49

|=ดำเนินการในสถานที่+การดำเนินการระหว่างคู่ของวัตถุ โดยเฉพาะอย่างยิ่งระหว่าง:

ในกรณีส่วนใหญ่จะเกี่ยวข้องกับตัว|ดำเนินการ ดูตัวอย่างด้านล่าง

ชุด

ตัวอย่างเช่นการรวมกันของสองชุดที่กำหนดs1และs2แบ่งปันนิพจน์ที่เทียบเท่ากันต่อไปนี้:

>>> s1 = s1 | s12                                          # 1
>>> s1 |= s2                                               # 2
>>> s1.__ior__(s2)                                         # 3

โดยที่ค่าสุดท้ายของs1เทียบเท่าโดย:

  1. การดำเนินการหรือที่ได้รับมอบหมาย
  2. ในสถานที่หรือการดำเนินการ
  3. การดำเนินการในสถานที่หรือด้วยวิธีพิเศษ++

ตัวอย่าง

ที่นี่เราใช้ OR ( |) และ inplace OR ( |=) กับชุด :

>>> s1 = {"a", "b", "c"}
>>> s2 = {"d", "e", "f"}

>>> # OR, | 
>>> s1 | s2
{'a', 'b', 'c', 'd', 'e', 'f'}
>>> s1                                                     # `s1` is unchanged
{'a', 'b', 'c'}

>>> # Inplace OR, |=
>>> s1 |= s2
>>> s1                                                     # `s1` is reassigned
{'a', 'b', 'c', 'd', 'e', 'f'}

พจนานุกรม

ในPython 3.9+จะมีการเสนอตัวดำเนินการmerge ( |) และ update ( |=) ใหม่ระหว่างพจนานุกรม หมายเหตุ: สิ่งเหล่านี้ไม่เหมือนกับตัวดำเนินการชุดที่กล่าวถึงข้างต้น

ให้การดำเนินการระหว่างสองคำสั่งที่ได้รับมอบหมายd1และd2:

>>> d1 = d1 | d2                                           # 1
>>> d1 |= d2                                               # 2

d1เทียบเท่าที่ไหนผ่าน:

  1. การดำเนินการผสานขวาที่ได้รับมอบหมาย
  2. การดำเนินการผสานขวา (อัพเดต) ในสถานที่ เทียบเท่ากับd1.update(d2)

ตัวอย่าง

ที่นี่เราใช้ merge ( |) และ update ( |=) เป็นdicts :

>>> d1 = {"a": 0, "b": 1, "c": 2}
>>> d2 = {"c": 20, "d": 30}

>>> # Merge, | 
>>> d1 | d2
{"a": 0, "b": 1, "c": 20, "d": 30}
>>> d1 
{"a": 0, "b": 1, "c": 2}

>>> # Update, |=
>>> d1 |= d2
>>> d1 
{"a": 0, "b": 1, "c": 20, "d": 30}

เคาน์เตอร์

collections.Counterเกี่ยวข้องกับ datastructure ทางคณิตศาสตร์ที่เรียกว่าMultiSet (mset) โดยพื้นฐานแล้วเป็นคำสั่งของคู่คีย์ - ค่า (object, multiplicity)

ให้การดำเนินการระหว่างสองเคาน์เตอร์ที่ได้รับมอบหมายc1และc2:

>>> c1 = c1 | c2                                           # 1
>>> c1 |= c2                                               # 2

c1เทียบเท่าที่ไหนผ่าน:

  1. การดำเนินการของสหภาพที่ได้รับมอบหมาย
  2. การดำเนินการของสหภาพแรงงานในสถานที่

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

ตัวอย่าง

ที่นี่เราใช้สหภาพ ( |) และสหภาพแทน ( |=) กับเคาน์เตอร์ :

import collections as ct


>>> c1 = ct.Counter({2: 2, 3: 3})
>>> c2 = ct.Counter({1: 1, 3: 5})

>>> # Union, |    
>>> c1 | c2
Counter({2: 2, 3: 5, 1: 1})
>>> c1
Counter({2: 2, 3: 3})

>>> # Inplace Union, |=
>>> c1 |= c2
>>> c1
Counter({2: 2, 3: 5, 1: 1})

ตัวเลข

สุดท้ายนี้คุณสามารถทำคณิตศาสตร์ไบนารีได้

ให้การดำเนินการระหว่างสองหมายเลขที่กำหนดn1และn2:

>>> n1 = n1 | n2                                           # 1
>>> n1 |= n2                                               # 2

n1เทียบเท่าที่ไหนผ่าน:

  1. การดำเนินการหรือการดำเนินการตามลำดับบิตที่กำหนด
  2. ในสถานที่บิตหรือการดำเนินการ

ตัวอย่าง

ที่นี่เราใช้ bitwise OR ( |) และตำแหน่ง bitwise OR ( |=) กับตัวเลข :

>>> n1 = 0
>>> n2 = 1

>>> # Bitwise OR, |
>>> n1 | n2
1
>>> n1
0

>>> # Inplace Bitwise OR, |=
>>> n1 |= n2
>>> n1
1

ทบทวน

ส่วนนี้สั้น ๆ จะทบทวนคณิตศาสตร์ระดับบิต ในกรณีที่ง่ายที่สุดการดำเนินการบิตหรือเปรียบเทียบสองบิตไบนารี มันก็จะกลับมายกเว้นเมื่อบิตทั้งสองเป็น10

>>> assert 1 == (1 | 1) == (1 | 0) == (0 | 1)
>>> assert 0 == (0 | 0)

ตอนนี้เราขยายความคิดนี้ไปไกลกว่าเลขฐานสอง เมื่อพิจารณาจากจำนวนอินทิกรัลสองจำนวนใด ๆ (ไม่มีส่วนประกอบที่เป็นเศษส่วน) เราใช้บิตหรือหรือและได้ผลลัพธ์ที่เป็นส่วนประกอบ:

>>> a = 10 
>>> b = 16 
>>> a | b
26

อย่างไร? โดยทั่วไปการดำเนินการในระดับบิตจะเป็นไปตาม "กฎ":

  1. เปรียบเทียบการเทียบเท่าไบนารีภายใน
  2. ใช้การดำเนินการ
  3. ส่งคืนผลลัพธ์เป็นประเภทที่กำหนด

ลองใช้กฎเหล่านี้กับจำนวนเต็มปกติด้านบน

(1) เปรียบเทียบการเทียบเท่าไบนารีที่เห็นในที่นี้เป็นสตริง ( 0bหมายถึงไบนารี):

>>> bin(a)
'0b1010'
>>> bin(b)
'0b10000'

(2) ใช้บิตหรือการดำเนินการกับแต่ละคอลัมน์ ( 0เมื่อทั้งสองเป็น0อย่างอื่น1):

01010
10000
-----
11010

(3) ส่งคืนผลลัพธ์ในประเภทที่กำหนดเช่นฐาน 10 ทศนิยม:

>>> int(0b11010)
26

การเปรียบเทียบไบนารีภายในหมายความว่าเราสามารถใช้ตัวหลังกับจำนวนเต็มในฐานใดก็ได้เช่นฐานสิบหกและฐานแปด:

>>> c = 0xa
>>> d = 0o32
>>> c | d
26

ดูสิ่งนี้ด้วย

+ ตัวดำเนินการแบบ in-place bitwise OR ไม่สามารถใช้กับตัวอักษรได้ กำหนดวัตถุให้กับชื่อ

++ วิธีพิเศษส่งคืนการดำเนินการเดียวกันกับตัวดำเนินการที่เกี่ยวข้อง


2
เพื่อความชัดเจนอย่างสมบูรณ์ฉันจะเพิ่มการสาธิตว่าหลังจากทำการกำหนดปกติ (x = x | y) id (x) มีการเปลี่ยนแปลงเนื่องจากเป็นวัตถุใหม่ในขณะที่ | = เก็บ id เดิมไว้เพราะเป็น x ดั้งเดิมที่ มีการแก้ไขดังนั้นชื่อ "inplace"
Florimond

1
นี่น่าจะเป็นคำตอบอันดับต้น ๆ - เป็นคำตอบที่ละเอียดถี่ถ้วนที่สุด
นิค

ในส่วนตัวเลขคุณกำลังอ้างว่าคำสั่งที่สองทำการดำเนินการในสถานที่ ฉันคิดว่ามันไม่เป็นความจริงเนื่องจากints ไม่สามารถเปลี่ยนแปลงได้ใน Python
Asocia

106

ในหลามและหลายภาษาโปรแกรมอื่น ๆ|เป็นค่าที่เหมาะสมหรือการดำเนินงาน |=เป็นไป|ตาม+=นั้น+คือการรวมกันของการดำเนินการและการลดระดับ

ดังนั้นสั้นสำหรับvar |= valuevar = var | value

กรณีการใช้งานทั่วไปคือการรวมสองชุด:

>>> a = {1,2}; a |= {3,4}; print(a)
{1, 2, 3, 4}

21
คุณช่วยยกตัวอย่างได้ไหม
แร่ธาตุ

ได้ให้กรณีการใช้งานที่ฉันพบด้านล่าง
scharfmn

53

เมื่อใช้กับชุดจะดำเนินการรวมกัน


1
ฉันกำลังอ่านโค้ดและ|=ใช้ในบริบทที่ตั้งไว้และมันก็ไม่ได้จนกว่าฉันจะยุ่งและคิดออกว่าฉันสังเกตเห็นคำตอบนี้อยู่ที่นี่ด้วย
TallChuck

41

นี่เป็นเพียงการดำเนินการ OR ระหว่างตัวแปรปัจจุบันกับอีกตัวแปรหนึ่ง เป็นT=TrueและF=Falseดูผลลัพธ์แบบกราฟิก:

r    s    r|=s
--------------
T    T    T
T    F    T
F    T    T
F    F    F

ตัวอย่างเช่น:

>>> r=True
>>> r|=False
>>> r
True
>>> r=False
>>> r|=False
>>> r
False
>>> r|=True
>>> r
True

7
สิ่งนี้ทำให้เกิดความรู้สึกวิปริตของผู้ปฏิบัติงาน |เป็นตัวดำเนินการแบบบิตหรือสำหรับจำนวนเต็มไม่ใช่ตัวดำเนินการบูลีนโดยเฉพาะและสำหรับสิ่งอื่นที่ไม่ใช่bools มันจะไม่สร้างTrueหรือFalseเอาท์พุตจริงๆ boolเป็น subclass ของintและจะดีพวกเขามากเกินไปสำหรับการboolที่จะทำให้การผลิตTrue/ Falseเอาท์พุท แต่ในกรณีส่วนใหญ่การดำเนินงานแบบบูลควรจะทำกับไม่or |การใช้งานปกติสำหรับ|บิตหรือหรือชุดยูเนี่ยน ตัวอย่างที่ดีของการใช้งานจะเป็นสิ่งที่ชอบซึ่งเป็นผู้ผลิตa = 0b1001; a |= 0b0010; print(bin(a)) 0b1011
ShadowRanger


3

เป็นบิตหรือ. สมมติว่าเรามี32 |= 10รูปภาพ 32 และ 10 เป็นไบนารี

32 = 10 0000
10 = 00 1010

ตอนนี้เพราะ | คือหรือทำแบบบิตหรือสองตัวเลข

เช่น 1 หรือ 0 -> 1, 0 หรือ 0 -> 0 ทำต่อไปตามโซ่

10 0000 | 00 1010 = 10 1010.

ตอนนี้เปลี่ยนไบนารีเป็นทศนิยม 10 1010 = 42

สำหรับ | = x +=5คิดในตัวอย่างที่รู้จักกัน มันหมายความว่าx = x + 5,ดังนั้นถ้าเรามีก็หมายความว่าx |= 5x = x bitwiseor with 5


นี่คือคำอธิบายที่ฉันกำลังมองหาทุกคนพูดถึงเซตและบูล แต่ไม่มีใครพูดถึงการใช้กับตัวเลข
Ankush Verma

ตัวอย่างที่คุณให้ไม่ได้ แต่32 |= 10 32 | 10เพียงเพื่อชี้แจงสิ่งนี้สำหรับผู้อ่านในอนาคต :)
sniper71

@ sniper71 ผลลัพธ์ของ 32 คืออะไร = 10
อนาคต - จิม

2

ใน Python | = (ior) ทำงานเหมือนกับการทำงานร่วมกัน เช่นถ้า x = 5 และ x | = 5 ค่าทั้งสองจะแปลงเป็นค่าไบนารีก่อนจากนั้นการดำเนินการรวมกันจะดำเนินการและเราได้รับคำตอบ 5


2

ในการให้กรณีการใช้งาน (หลังจากใช้เวลากับคำตอบอื่น ๆ ):

def process(item):
   return bool(item) # imagine some sort of complex processing taking place above

def any_success(data): # return True if at least one is successful
    at_least_one = False
    for item in data:
       at_least_one |= process(item)
    return at_least_one

>>> any_success([False, False, False])
False
>>> any_success([True, False, False])
True
>>> any_success([False, True, False])
True

โดยพื้นฐานแล้วanyไม่มีการลัดวงจร: อาจมีประโยชน์หากคุณต้องการดำเนินการทุกรายการและบันทึกความสำเร็จอย่างน้อยหนึ่งรายการเป็นต้น

ดูคำเตือนในคำตอบนี้ด้วย

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