本文主要是介绍从位运算看海象运算符,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- 前言
- 需求
- 先找出需要多少位数
- 使用限制
- 赋值场景
- 判断场景
- 转为one-hot编码
- 一件小事情
前言
突然发现了Python3.8版本引入的海象运算符,就借着位运算的需求来看看是怎么个用法。
需求
需求是这样的,我有一张表,表中存在很多类东西,每个类都有一个自增编号。为了让自增编号转变为one-hot
编码,需要将自增的编号转换为二进制。
当然,确实是可以直接使用Python
的二进制转换工具,但那样就完全没意思了不是吗?
先找出需要多少位数
首先,我们需要知道,自增编号的最大值是多少。
既然是表里面存储的,那么这一点就比较好办:
SELECT MAX(id) FROM table_name;
不管你用jdbc
也好,ODBC
也罢,反正你拿到了这个最大值。于是你开始准备着手计算:
def get_max_length(max_id):count = 1while max_id := max_id >> 1:count += 1return count
这就是海象运算符的用法。在判断的时候,先计算海象运算符右侧,然后把结果赋值给左侧,最后判断左值是否满足条件。
使用限制
当然,这并不是Go
语言,所以海象运算符并不是哪里都能用。
赋值场景
在赋值过程中,如果搭配括号,那么海象运算符与赋值符号是完全一致的。
a = (a - 30) / 2
这个看着相当简单。而如果我说可以用海象运算符装个莫名其妙的逼呢?
a = (a := (a := a - 30) / 2)
看起来很诡异,但是原理上与传统的赋值符号用法完全一致。毕竟二者都是一个顺序:
先计算右值、再赋给左值。
当然,二者也不是完全不同。海象运算符不可以直接赋值。
传统赋值过程中,如果我们是可以直接指定的:
a = 30
海象运算符不一样,会报错:
a := 30
~~^^~~~
这就是为什么,我们在装逼的时候,最左边的赋值还只能是=
符号。
判断场景
海象运算符最大的特点就是,本身返回的是值,所以判断场景才是海象运算符最常用的场景。就比如说,我需要移位,传统过程只能这么做:
a = a >> 1
if a > 0:print(a)
因为=
没有返回值,只能将右值给到左值。
海象运算符不一样,在将右值给到左值的基础上,还能够把左值返回出去:
if a := a >> 1:print(a)
不过需要注意的是,海象运算符的优先级比较低,在真实场景使用的时候需要带上括号:
if a := 30 > 40:print(a) # 不输出
print(a) # 输出False,因为优先级算了30 > 40
转为one-hot编码
当然,由于是one-hot
编码,我们并不能直接使用二进制数值,因为这样做无法转为矩阵。
不过好在,我们还有海象运算符,我们可以这么做:
def transfer2b(num):# 先把最初的一位数加进去onehot = [num & 1]# 海象运算符循环处理while num := num >> 1:# 使用切片的方式增加数据onehot[:0] = [num & 1]# 由于并非极端场景,所以与`insert`差距不大# 下面是`insert`写法:# onehot.insert(0, num & 1)return onehot
那么我们在使用的时候就会很方便:
print(transfer2b(64)) # 输出:[1, 0, 0, 0, 0, 0, 0]
一件小事情
最开始的时候,我始终认为 64 64 64是只需要 6 6 6位二进制,后来才想起来,用二进制表示的时候还有一个 0 0 0需要表示。
所以,如果是 64 64 64,其实需要 7 7 7位,因为 6 6 6位只能够表示 0 ∼ 2 6 − 1 0\sim2^6-1 0∼26−1。数字虽然确实是有 64 64 64个,但由于从 0 0 0开始,所以实际最大也就少了一个。
这篇关于从位运算看海象运算符的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!