【问题标题】:What does |= (ior) do in Python?|= (ior) 在 Python 中做了什么?
【发布时间】:2010-10-14 01:00:13
【问题描述】:

Google 不允许我搜索 |=,因此我无法找到相关文档。有人知道吗?

【问题讨论】:

  • 我认为有必要指出,正如下面sunny 的回答,| 也被用作集合联合运算符
  • 2019年谷歌让你搜索`|=`! :-)

标签: python


【解决方案1】:

|= 在对象对之间执行 in-place+ 操作。特别是在:

在大多数情况下,它与| 运算符有关。请参阅下面的示例。

套装

例如,两个分配集s1s2 的并集共享以下等价表达式:

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

s1 的最终值等于:

  1. 分配的 OR 操作
  2. 就地 OR 操作
  3. 通过特殊方法进行就地 OR 操作++

例子

在这里,我们将 OR (|) 和就地 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'}

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

字典

Python 3.9+ 中,字典之间提出了新的合并(|)和更新(|=)运算符。注意:这些与上面提到的集合运算符不同。

给定两个分配的字典 d1d2 之间的操作:

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

其中d1 等价于:

  1. 分配的合并权限操作
  2. 就地合并权限(更新)操作;相当于d1.update(d2)

例子

在这里,我们将合并 (|) 和更新 (|=) 应用于 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 与称为multiset (mset) 的数学数据结构相关。它基本上是(对象,多重性)键值对的字典。

给定两个分配的计数器 c1c2 之间的操作:

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

其中c1 等价于:

  1. 分配的联合操作
  2. 就地联合操作

union of multisets 包含每个条目的最大重数。请注意,这与两个集合之间或两个常规字典之间的行为方式不同。

例子

在这里,我们将联合 (|) 和就地联合 (|=) 应用于 Counters

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

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

数字

最后,你可以做二进制数学。

给定两个分配数字n1n2之间的运算:

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

其中n1 等价于:

  1. 分配的按位或运算
  2. 就地按位或运算

例子

这里我们将按位或 (|) 和就地按位或 (|=) 应用于数字

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

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

>>> # In-place Bitwise OR, |=
>>> n1 |= n2
>>> n1
1

评论

本节简要回顾一些按位数学。在最简单的情况下,按位或运算比较两个二进制位。它将始终返回1,除非两个位都是0

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

内部二进制比较意味着我们可以将后者应用于任何基数的整数,例如十六进制和八进制:

>>> a = 10                                   # 10, dec
>>> b = 0b10000                              # 16, bin
>>> c = 0xa                                  # 10, hex
>>> d = 0o20                                 # 16, oct

>>> a | b
26
>>> c | d
26

另见

+就地按位或运算符不能应用于文字;将对象分配给名称。

++特殊方法返回与其对应的操作符相同的操作。

【讨论】:

  • 为了非常清楚,我将添加到演示中,在执行常规分配 (x = x | y) 后,id(x) 已更改,因为它是一个新对象,而 |= 保留相同的 id,因为它是被修改的原始 x,因此名称为“inplace”。
  • 这应该是最佳答案 - 这是最详尽的。
  • 在数字部分,您声称第二条语句执行就地操作。我认为这不是真的,因为ints 在 Python 中是不可变的。
  • 解释得很漂亮。谢谢!
  • 即使认为 int 没有 ior 方法,a=1, a |= 2 怎么会起作用?子类化 int 时有办法覆盖|= 吗?
【解决方案2】:

在 Python 和许多其他编程语言中,|bitwise-OR operation|=| 就像 +=+,即操作和赋值的组合。

所以var |= valuevar = var | value 的缩写。

一个常见的用例是合并两个集合:

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

【讨论】:

  • 你能举个例子吗?
  • 给出了我在下面遇到的一个用例
【解决方案3】:

当与集合一起使用时,它执行联合操作。

【讨论】:

  • 我正在阅读一些代码,|= 在设置的上下文中使用,直到我搞砸了,才发现这个答案也在这里
【解决方案4】:

这只是当前变量和另一个变量之间的 OR 操作。作为T=TrueF=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

【讨论】:

  • 这会给操作者一种扭曲的印象; | 是整数的按位或运算符,而不是布尔运算符,对于 bools 以外的任何东西,它实际上不会产生 TrueFalse 输出。 boolint 的一个子类,为了很好,他们为 bool 重载它以继续产生 True/False 输出,但在大多数情况下,布尔运算应该使用 or 完成,不是|| 的正常用法是按位或或集合联合。更好的使用示例是像a = 0b1001; a |= 0b0010; print(bin(a)) 这样产生0b1011
【解决方案5】:

它对赋值的左侧和右侧执行二进制按位或,然后将结果存储在左侧变量中。

http://docs.python.org/reference/expressions.html#binary-bitwise-operations

【讨论】:

    【解决方案6】:

    按位或。 假设我们有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 |= 5,则表示x = x bitwiseor with 5

    【讨论】:

    • 这是我一直在寻找的解释,每个人都在谈论集合和布尔值,但没有人提到它与数字的用途。
    • 你给出的例子不是32 |= 10,而是32 | 10。只是为了向未来的读者澄清这一点:)
    • @sniper71 32 |= 10 的结果是什么
    • 32 |= 10 是语法错误,因为32 不是有效的赋值目标。
    【解决方案7】:

    在 Python 中,|=(ior) 的工作方式类似于联合操作。 就像如果 x=5 和 x|=5 那么这两个值都会首先转换为二进制值,然后执行联合运算,我们得到答案 5。

    【讨论】:

      【解决方案8】:

      给出一个用例(在花时间回答其他答案之后):

      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 没有短路:如果您需要处理每个项目并记录至少一次成功等,这可能会很有用。

      另请参阅this answer 中的注意事项

      【讨论】:

        猜你喜欢
        • 2019-01-13
        • 2020-10-13
        • 2018-12-04
        • 2011-03-10
        • 1970-01-01
        • 2013-07-09
        • 2011-06-18
        • 2020-05-23
        • 2020-03-19
        相关资源
        最近更新 更多