简单了解python的一些位运算技巧


Posted in Python onJuly 13, 2019

前言

位运算的性能大家想必是清楚的,效率绝对高。相信爱好源码的同学,在学习阅读源码的过程中会发现不少源码使用了位运算。但是为啥在实际编程过程中应用少呢?想必最大的原因,是较为难懂。不过,在面试的过程中,在手写代码过程中,写出一两个位运算的代码,还会让面试官眼前一亮的。

位运算常用的运算符包括&(按位与), | (按位或),~(按位非),^(按位异或),<< (有符号左移位) ,>>(有符号右移位)。

简单了解python的一些位运算技巧

下面用几个例子说明其应用,希望对你有所启发。

1、判断奇数还是偶数

通常判断奇数还是偶数我们想到的办法就是除以2,看余数是否为0。

Python代码如下:

def isodd(x):
 return True if (x % 2 <> 0) else False

如何使用位运算呢?

我们只需要使用&运算,与1进行&,如果为1,那么该数为奇数;如果为0,那么该数是偶数,Python代码如下:

def isodd(x):
 return True if (x & 1) else False

2、左移一位相当于乘以2,右移一位相当于除以2

在面试的过程中,通常会遇到的一个问题是写二分查找代码。

二分查找的代码如下:

def binary_search(list, item):
 '''
 :param list: 有序列表
 :param item: 要查找的元素
 :return: item在list中的索引,若不在list中返回None
 '''
 low = 0
 high = len(list) - 1
 while low <= high:
 midpoint = (low + high) // 2
 if list[midpoint] == item:
 return midpoint
 elif list[midpoint] < item:
 low = midpoint + 1
 elif list[midpoint] > item:
 high = midpoint - 1
 return None

其中有一步是需要取最小小标和最大下标的中间值,若使用位运算符,midpoint = (low + high) >> 1,面试官肯定会对你刮目相看。

3、交换两个数值

数值交换的代码相信大家都非常熟悉了,因为似乎是从学编程语言的最开始就一直用:

temp = b
b = a
a = temp

但是怎么使用位运算来完成此功能呢?

a ^= b
b ^= a
a ^= b

确实比较难理解,原理是什么呢?

第一行,a = a ^ b,很容易理解;

第二行, b = b ^ a = b ^ a ^ b,由于 b ^ b = 0,所以 b = a ^ 0,即 b = a;

第三行, a = a ^ b ,由于a在第一步重新赋值,所以,a = a ^ b ^ a = b,完成了数值交换。

这里,总结下异或运算的特性:任意数和自身异或结果为0;0和任意数异或结果还是其本身。

4、寻找数据列表中的独一无二

有一个数据列表(2N+1个整数),只有一个数出现了1次,其余N个数都出现了2次。如何找到这个独一无二的数据?

看到这个题目,相信大家第一次想到的算法肯定是计数,建立列表,循环整个数据并计数,然后遍历这个列表找到出现次数为1的数据。

这样,空间复杂度为O(N)。

如何降低空间复杂度呢?

注意看一下刚刚讲过的异或的特性:任意数和自身异或结果为0;0和任意数异或结果还是其本身。

那么,出现了2次的N个数异或的结果是0,再与出现次数为1次的数异或的结果即为该数。即:找到这个独一无二数据的办法是通过对全部的数据进行异或操作,空间复杂度降低为O(1)。

5、计算一个数值的二进制数中有多少个1

相信有了之前的基础,大家很容易实现这个算法。单纯的通过位运算,与1进行与运算,看是否结果为1,然后右移1位,继续判断。Python代码实现如下:

def number1Bit(x):
 count = 0
 while x:
 count = count + (x&1)
 x = x >> 1
 return count

这样存在一个问题,就是如果有连续多个0,那么需要做多次移位操作。有没有简单的方式跳过连续多个0的情况?

那就是通过与(x-1)进行&运算。这里可能不太好理解,举例说明一下

x 1110 0000
x - 1 1101 1111
x&(x-1) 1100 0000

通过这种方式,会把最后的那个1检测出来。

Python代码实现如下:

def number1Bit(x):
 count = 0
 while x:
 count = count + 1
 x = x & (x-1)
 return count

总结:

1、与运算通常应用的场景是获取某一位的值为1还是0(如判断奇数偶数,统计数值中1的个数);

2、左移右移特性:左移一位相当于乘以2,右移一位相当于除以2;

3、异或特性:任意数和自身异或结果为0;0和任意数异或结果还是其本身。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python 命令行非阻塞输入的小例子
Sep 27 Python
python基础教程之常用运算符
Aug 29 Python
python opencv实现任意角度的透视变换实例代码
Jan 12 Python
Python设计模式之组合模式原理与用法实例分析
Jan 11 Python
Python微信操控itchat的方法
May 31 Python
Python多进程入门、分布式进程数据共享实例详解
Jun 03 Python
python pygame实现滚动横版射击游戏城市之战
Nov 25 Python
python如何求数组连续最大和的示例代码
Feb 04 Python
详解PyQt5信号与槽的几种高级玩法
Mar 24 Python
Python异常原理及异常捕捉实现过程解析
Mar 25 Python
如何理解Python中的变量
Jun 01 Python
基于Python绘制美观动态圆环图、饼图
Jun 03 Python
简单了解python PEP的一些知识
Jul 13 #Python
python爬虫神器Pyppeteer入门及使用
Jul 13 #Python
Python 分享10个PyCharm技巧
Jul 13 #Python
简单了解Python3里的一些新特性
Jul 13 #Python
python将类似json的数据存储到MySQL中的实例
Jul 12 #Python
Django对数据库进行添加与更新的例子
Jul 12 #Python
Python 绘制酷炫的三维图步骤详解
Jul 12 #Python
You might like
php foreach循环中使用引用的问题
2013/11/06 PHP
检查用户名是否已在mysql中存在的php写法
2014/01/20 PHP
PHP把空格、换行符、中文逗号等替换成英文逗号的正则表达式
2014/05/04 PHP
php 删除一维数组中某一个值元素的操作方法
2018/02/01 PHP
基础的prototype.js常用函数及其用法
2007/03/10 Javascript
兼容IE/Firefox/Opera/Safari的检测页面装载完毕的脚本Ext.onReady的实现
2009/07/14 Javascript
javascript Array.prototype.slice使用说明
2010/10/11 Javascript
jquery复选框多选赋值给文本框的方法
2015/01/27 Javascript
JavaScript动态修改网页元素内容的方法
2015/03/21 Javascript
原生js模拟淘宝购物车项目实战
2015/11/18 Javascript
jQuery UI制作选项卡(tabs)
2016/12/13 Javascript
js正则表达式最长匹配(贪婪匹配)和最短匹配(懒惰匹配)用法分析
2016/12/27 Javascript
浅谈JS对html标签的属性的干预以及对CSS样式表属性的干预
2017/06/25 Javascript
通俗解释JavaScript正则表达式快速记忆
2017/08/23 Javascript
vue+element树组件 实现树懒加载的过程详解
2019/10/21 Javascript
vue请求服务器数据后绑定不上的解决方法
2019/10/30 Javascript
JavaScript中的Proxy对象
2020/11/27 Javascript
Python进阶学习之特殊方法实例详析
2017/12/01 Python
numpy 进行数组拼接,分别在行和列上合并的实例
2018/05/08 Python
Django+Xadmin构建项目的方法步骤
2019/03/06 Python
Pycharm 文件更改目录后,执行路径未更新的解决方法
2019/07/19 Python
Python编程快速上手——Excel表格创建乘法表案例分析
2020/02/28 Python
win10下opencv-python特定版本手动安装与pip自动安装教程
2020/03/05 Python
pycharm 添加解释器的方法步骤
2020/08/31 Python
Python引入多个模块及包的概念过程解析
2020/09/21 Python
美国床垫和床上用品公司:Nest Bedding
2017/06/12 全球购物
联想德国官网:Lenovo Germany
2018/07/04 全球购物
乌克兰在线电子产品商店:MTA
2019/11/14 全球购物
质检的岗位职责
2013/11/17 职场文书
竞争性谈判邀请书
2014/02/06 职场文书
不忘国耻振兴中华演讲稿
2014/05/14 职场文书
信息合作协议书
2014/10/09 职场文书
售后服务质量承诺书
2015/04/29 职场文书
2015年路政工作总结
2015/05/22 职场文书
2015年高二班主任工作总结
2015/05/25 职场文书
JavaScript parseInt0.0000005打印5原理解析
2022/07/23 Javascript