在Python中,>>和<<是什么意思?

246

我注意到我可以像 2 << 5 这样做来得到 64 ,以及 1000 >> 2 来得到 250。

同时我也可以在 print 中使用>>

print >>obj, "Hello world"

这里发生了什么?


5
常见问题:运算符 <<>>&|~^ 的含义是什么?这些运算符是位运算符,用于操作二进制数字的每一位。具体地说:
  • << 为左移运算符,将数字的所有位向左移动指定数量的位数,并在右侧添加零。例如,2 << 2 等于 8。
  • >> 为右移运算符,将数字的所有位向右移动指定数量的位数,并在左侧添加零或一(根据数字的符号)。例如,11 >> 1 等于 5。
  • & 为按位与运算符,将两个数字的每一位进行逻辑与运算。只有两个相应的位都为 1 时,结果才为 1。例如, 5 & 3 等于 1。
  • | 为按位或运算符,将两个数字的每一位进行逻辑或运算。只要两个相应的位中至少有一个 1,结果就为 1。例如,5 | 3 等于 7。
  • ~ 为按位取反运算符,将数字的每一位进行逻辑非运算,即 0 变成 1,1 变成 0。例如,~5 等于 -6。
  • ^ 为按位异或运算符,将两个数字的每一位进行逻辑异或运算。只有两个相应的位中恰好一个为 1 时,结果才为 1。例如,5 ^ 3 等于 6。
- Ashwini Chaudhary
6
现在,你可以把那些符号输入到搜索引擎中并进行搜索:http://symbolhound.com。 - user2357112
可能是位运算及其用法的重复问题。 - vaultah
3
非常感谢,这将非常有帮助。对于那些认为这是基本问题的人来说,可能确实是,但我没有位运算符的概念,所以我从未想过在文档中查找它...... - user3201152
@joaquin,现在在谷歌上搜索“Python大于大于”已经成为排名第一的结果。 - Jordan Reiter
在第一种情况下,它是位移运算符,在第二种情况下,它被重载为StringIO()对象。请查看此print chevron - GiriB
10个回答

155
你的例子中的 >> 运算符用于两个不同的目的。在 C++ 中,这个运算符被重载了。在第一个例子中,它被用作位运算符(右移),right shift
2 << 5  # shift left by 5 bits
        # 0b10 -> 0b1000000
1000 >> 2  # shift right by 2 bits
           # 0b1111101000 -> 0b11111010

在第二种情况下,它用于输出重定向。您可以像这个例子一样与文件对象一起使用它:
with open('foo.txt', 'w') as f:
    print >>f, 'Hello world'  # "Hello world" now saved in foo.txt

这里提到的>>只适用于Python 2。在Python 3中可以使用file=参数来重定向print()的输出:

with open('foo.txt', 'w') as f:
    print('Hello world', file=f)  # "Hello world" now saved in foo.txt

63
FYI,你可能会在Python代码中看到另一种常见的右移运算符用法,它将出现在Airflow文件中。Airflow框架重载了'>>'运算符,以表示一个任务在另一个任务的上游:https://dev59.com/PFQK5IYBdhLWcg3wJMkm - schimmy
7
你实际上可以通过 __rshift____lshift__ 方法覆盖这些运算符。 - trudolf
我发现 2 >> 5 等于 0。 我以为它应该等于 0.0001? - lightbox142
2
@teter123f,这是二进制操作,不是十进制操作。 - yosemite_k

117

这些是位移操作符。

引用自文档

x << y

x 的二进制位向左移动 y 位(新的右侧位为零)。这与将 x 乘以 2**y 相同。

x >> y

x的二进制位向右移动y位后返回结果。与其等价的除法表达式为x除以2**y


6
或许举个例子会有所帮助,在Python中输入以下一系列代码:print bin(1), print bin(1 << 1), print bin(17), print bin(17 >> 1) 等等。你可以看到它们是如何工作的,无需解释。 - user1472229
5
位移操作符需要两个操作数,为什么第一个操作数是"print",而第二个操作数是一个对象?例如:print >>obj, "Hello world" - Qi Fan
这是对提问者提供的背景信息(因此提问者已知)的回答,而不是针对所问的问题的回答。 - z33k
1
@Qi Fan @z33k 这个问题被编辑后添加了有关打印的引用,而这个答案是一年多之前写的。原始问题仅提到 2 << 51000 >> 2 ¯_(ツ)_/¯ - James

63

12 << 2

48

在执行上述语句时,十进制数12的二进制表示为“00 1100”,左移2位(即向左移动2个位置)返回值48,其二进制表示为“11 0000”。

48 >> 2

12

在执行上述语句时,十进制数48的二进制表示为“11 0000”,右移2位(即向右移动2个位置)返回值12,其二进制表示为“00 1100”。


39

位移运算符在许多主流编程语言中都存在,<<是左移运算符,>>是右移运算符,可以通过以下表格进行演示,假设一个整数仅占用1个字节的内存。

| operate | bit value | octal value |                       description                        |
| ------- | --------- | ----------- | -------------------------------------------------------- |
|         | 00000100  |           4 |                                                          |
| 4 << 2  | 00010000  |          16 | move all bits to left 2 bits, filled with 0 at the right |
| 16 >> 2 | 00000100  |           4 | move all bits to right 2 bits, filled with 0 at the left |

正在准确地搜索此说明。 - shaik moeed

15
涉及print >>obj, "Hello World"的另一种情况是Python 2中print语句的“打印chevron”语法(在Python 3中已删除,由print()函数的file参数取代)。输出不是写入标准输出,而是传递给obj.write()方法。 典型示例是具有write()方法的文件对象。请参阅更近期问题的答案:Python中的双大于号

10

这些是位运算符的移位操作符

x << y 返回经过左移y位后的x(右边新位上的数字为0)。这与将x乘以2**y相同。

x >> y 返回经过右移y位后的x。这与将x整除2**y相同。


7
这是有关"按位"操作符的内容。 https://wiki.python.org/moin/BitwiseOperators
>>> help("symbols")

+-------------------------------------------------+---------------------------------------+
| Operator                                        | Description                           |
|=================================================|=======================================|
| "<<", ">>"                                      | Shifts                                |
+-------------------------------------------------+---------------------------------------+
| "&"                                             | Bitwise AND                           |
+-------------------------------------------------+---------------------------------------+
| "|"                                             | Bitwise OR                            |
+-------------------------------------------------+---------------------------------------+
| "~x"                                            | bitwise NOT                           |
+-----------------------------------------------------------------------------------------+
| "^"                                             | Bitwise XOR                           |
+-------------------------------------------------+---------------------------------------+

x << y

返回将x向左移动y位后的结果(新位于右侧的位为零)。这与将x乘以2**y相同。

x >> y

返回将x向右移动y位后的结果。这与将x//'ing 2 ** y相同。

注意: 在Python 3.9中,运用于字典的" | "操作符用于合并字典。

https://docs.python.org/3.9/whatsnew/3.9.html

>>> x = {"key1": "value1 from x", "key2": "value2 from x"}
>>> y = {"key2": "value2 from y", "key3": "value3 from y"}
>>> x | y
{'key1': 'value1 from x', 'key2': 'value2 from y', 'key3': 'value3 from y'}
>>> y | x
{'key2': 'value2 from x', 'key3': 'value3 from y', 'key1': 'value1 from x'}


4

2 << 5(左移位运算)

将数字2(二进制形式下)向左移动5位(在右侧补0)。

bin(16) # '0b10'

shifted = bin(2) + '0' * 5 # '0b1000000'

int(shifted, 2) # 64
2 << 5 # 64

1000 >> 2 (向右移位)

将1000(二进制)向右移动2位。(在左侧补0)

bin(1000) # '0b1111101000'

# add 00 to the left and remove last digit from the right
# '0b 00(add these bits) 11111010 00(remove these bits)'
shifted = '0b0011111010'

int(shifted, 2) # 250
1000 >> 2 # 250

1
我在Python 2.7和Python 3.8上验证了以下内容。
我执行了print(100<<3)。 将100转换为二进制得到1100100。 我丢弃了前三位,然后在末尾添加了三位值为'0'的位。 所以应该得到0100000,我将其转换为十进制,答案是32。
令我惊讶的是,当我执行print(100<<3)时,答案是800。我感到困惑。 我将800转换为二进制以了解情况。 结果是1100100000。
如果你看一下Python的答案800,他们没有移动或丢弃前三位,而是在最后三位添加了值'0'。
而print(100>>3),则完美地工作。我进行了手动计算,并检查了Python的打印结果。它工作正常。丢弃了最后三位并在前三位添加了值'0'。
看起来(100<<3),即左移运算符,在Python上存在一个错误。

1
没有错误,它只是每个数字不限于8位。 - Andy
左移(<<)和右移(>>)运算符应该具有相同的逻辑。但是左移运算符表现出了不同的行为。我刚向 Python 提交了一个行为错误报告。 - Nandish
@Nandish 为什么...他们都使用相同的逻辑,都能正常工作 - Davo

0
<< Mean any given number will be multiply by 2the power
for exp:- 2<<2=2*2'1=4
          6<<2'4=6*2*2*2*2*2=64

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接