简单了解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中解析JSON并同时进行自定义编码处理实例
Feb 08 Python
Python 数据处理库 pandas进阶教程
Apr 21 Python
Flask框架信号用法实例分析
Jul 24 Python
Python用61行代码实现图片像素化的示例代码
Dec 10 Python
说说如何遍历Python列表的方法示例
Feb 11 Python
Python判断对象是否为文件对象(file object)的三种方法示例
Apr 26 Python
浅谈Python中函数的定义及其调用方法
Jul 19 Python
使用Tkinter制作信息提示框
Feb 18 Python
PyQt中使用QtSql连接MySql数据库的方法
Jul 28 Python
如何基于Django实现上下文章跳转
Sep 16 Python
使用Python脚本对GiteePages进行一键部署的使用说明
May 27 Python
详解非极大值抑制算法之Python实现
Jun 28 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中文汉字验证码
2007/04/08 PHP
PHP编码转换
2012/11/05 PHP
Laravel框架学习笔记(一)环境搭建
2014/10/15 PHP
CI(Codeigniter)的Setting增强配置类实例
2016/01/06 PHP
PHP与SQL语句写一句话木马总结
2019/10/11 PHP
js用图作提交按钮或超连接
2008/03/26 Javascript
JQuery上传插件Uploadify使用详解及错误处理
2010/04/27 Javascript
浅析Prototype的模板类 Template
2011/12/07 Javascript
JS替换文本域内的回车示例
2014/02/18 Javascript
详解js产生对象的3种基本方式(工厂模式,构造函数模式,原型模式)
2017/01/09 Javascript
浅谈JavaScript中promise的使用
2017/01/11 Javascript
vue 怎么创建组件及组件使用方法
2017/07/27 Javascript
解决bootstrap模态框数据缓存的问题方法
2018/08/10 Javascript
利用React Router4实现的服务端直出渲染(SSR)
2019/01/07 Javascript
js实现窗口全屏示例详解
2019/09/17 Javascript
vue实现文字加密功能
2019/09/27 Javascript
JavaScript实现下拉列表
2021/01/20 Javascript
[55:32]2018DOTA2亚洲邀请赛 4.4 淘汰赛 EG vs LGD 第二场
2018/04/05 DOTA
Python循环语句之break与continue的用法
2015/10/14 Python
解决Python出现_warn_unsafe_extraction问题的方法
2016/03/24 Python
Python使用SocketServer模块编写基本服务器程序的教程
2016/07/12 Python
Python栈算法的实现与简单应用示例
2017/11/01 Python
python如何派生内置不可变类型并修改实例化行为
2018/03/21 Python
详解将Django部署到Centos7全攻略
2018/09/26 Python
使用Python 正则匹配两个特定字符之间的字符方法
2018/12/24 Python
Python如何脚本过滤文件中的注释
2020/05/27 Python
HTML5本地存储之IndexedDB
2017/06/16 HTML / CSS
HTML5离线应用与客户端存储的实现
2018/05/03 HTML / CSS
Levi’s西班牙官方网站:李维斯,著名的牛仔裤品牌
2020/08/20 全球购物
制药工程专业个人求职自荐信
2014/01/25 职场文书
社区节水倡议书
2015/04/29 职场文书
美丽人生观后感
2015/06/03 职场文书
Python中super().__init__()测试以及理解
2021/12/06 Python
MySQL创建管理RANGE分区
2022/04/13 MySQL
vue如何在data中引入图片的正确路径
2022/06/05 Vue.js
spring 项目实现限流方法示例
2022/07/15 Java/Android