当前位置:首页>python>Python位运算符实战练习

Python位运算符实战练习

  • 2026-09-08 22:27:04
Python位运算符实战练习
[写在前面]可以参看我的视频进行学习,喜欢的话点个关注。

案例一:判断奇偶数(最常用技巧)

# 传统写法
defis_odd(n):
returnn%2==1

# 位运算写法(效率更高)
defis_odd_bit(n):
returnn&1==1# 与1相与,只看最后一位

# 练习:判断 7 和 10 的奇偶性
print(7&1)   # 1 → 奇数
print(10&1)  # 0 → 偶数

# 一行代码判断
print("奇数"if7&1else"偶数")

原理:二进制末位为1是奇数,为0是偶数。& 1 操作只保留最后一位。


案例二:快速乘除2的幂(面试常考)

# 左移 << 相当于乘以2的n次方
a=5
print(a<<1)  # 10  (5×2)
print(a<<2)  # 20  (5×4)

# 右移 >> 相当于除以2的n次方(整数)
b=20
print(b>>1)  # 10  (20÷2)
print(b>>2)  # 5   (20÷4)

# ⚠️ 练习:用位运算实现乘以8
defmultiply_by_8(n):
returnn<<3# 2³ = 8

# 验证
print(multiply_by_8(7))  # 56

案例三:交换两个数(不用临时变量)

a, b=5, 3
print(f"交换前: a={a}, b={b}")

# Python传统写法(直接解包)
# a, b = b, a

# 位运算方式(异或^)
a=a^b# a = 5^3 = 6 (110)
b=a^b# b = 6^3 = 5 (101) → 原来的a
a=a^b# a = 6^5 = 3 (011) → 原来的b

print(f"交换后: a={a}, b={b}")

# 练习:解释为什么异或能交换?
# 提示:a^a=0, a^0=a,异或满足交换律和结合律

案例四:权限系统设计(实际应用)

# 定义权限常量(2的幂次,确保二进制只有一位是1)
READ=1<<0# 0001 = 1
WRITE=1<<1# 0010 = 2
EXECUTE=1<<2# 0100 = 4
DELETE=1<<3# 1000 = 8

# 给用户授权(用或运算|组合权限)
user_permission=READ|WRITE# 0011 = 3

# 检查是否有某权限(用与运算&)
defhas_permission(user_perm, perm):
return (user_perm&perm) ==perm

# 练习场景
print(has_permission(user_permission, READ))     # True
print(has_permission(user_permission, DELETE))   # False

# 移除权限(用与非运算)
user_permission&=~WRITE# 移除写权限
print(has_permission(user_permission, WRITE))    # False

# 添加权限
user_permission|=DELETE# 添加删除权限
print(bin(user_permission))  # 0b1001

案例五:判断2的幂(算法题高频)

defis_power_of_two(n):
"""
    2的幂二进制特点:只有一位是1(如 1000, 100, 10, 1)
    n & (n-1) 会将最低位的1变成0
    """
returnn>0and (n& (n-1)) ==0

# 验证
print(is_power_of_two(8))   # True  (1000)
print(is_power_of_two(7))   # False (0111)
print(is_power_of_two(1))   # True  (1)
print(is_power_of_two(0))   # False

# 练习:解释 8 & 7 的结果
# 8 = 1000, 7 = 0111 → 1000 & 0111 = 0000
print(f"8 & 7 = {8&7}")  # 0

案例六:RGB颜色值提取(前端实用)

color=0xFF5733# 十六进制颜色值

# 提取红色通道(右移16位,取低8位)
r= (color>>16) &0xFF# 255

# 提取绿色通道(右移8位,取低8位)
g= (color>>8) &0xFF# 87

# 提取蓝色通道(直接取低8位)
b=color&0xFF# 51

print(f"RGB({r}, {g}, {b})")  # RGB(255, 87, 51)

# 练习:将 RGB(100, 150, 200) 合并为十六进制
defrgb_to_hex(r, g, b):
return (r<<16) | (g<<8) |b

hex_color=rgb_to_hex(100, 150, 200)
print(f"0x{hex_color:06X}")  # 0x6496C8
print(f"#{hex_color:06X}")   # #6496C8

案例七:统计二进制中1的个数(汉明重量)

defcount_ones(n):
"""统计整数二进制表示中1的个数"""
count=0
whilen:
n&= (n-1)  # 消除最低位的1
count+=1
returncount

# 验证
print(count_ones(0b1011))  # 3
print(count_ones(0b1000))  # 1

# Python内置方法(面试时展示了解)
print(bin(0b1011).count('1'))  # 3

# 进阶:使用Brian Kernighan算法
defcount_ones_bk(n):
count=0
whilen:
n&=n-1# 关键操作:每次消除最右边的1
count+=1
returncount

案例八:布隆过滤器原理(进阶应用)

classSimpleBloomFilter:
"""简单布隆过滤器:用位数组判断元素可能存在/肯定不存在"""

def__init__(self, size=32):
self.bits=0# 用整数模拟位数组

def_hash(self, s, seed):
"""简单哈希函数"""
h=seed
forcharins:
h= ((h<<5) -h) +ord(char)
returnabs(h) %32

defadd(self, item):
"""添加元素(设置对应位为1)"""
h1=self._hash(item, 1)
h2=self._hash(item, 2)
self.bits|= (1<<h1)
self.bits|= (1<<h2)

defmight_contain(self, item):
"""查询(如果对应位都是1,可能存在)"""
h1=self._hash(item, 1)
h2=self._hash(item, 2)
mask= (1<<h1) | (1<<h2)
return (self.bits&mask) ==mask

# 练习演示
bf=SimpleBloomFilter()
bf.add("apple")
bf.add("banana")

print(bf.might_contain("apple"))   # True(一定存在)
print(bf.might_contain("banana"))  # True(一定存在)
print(bf.might_contain("grape"))   # False(肯定不存在)或 True(误判)

print(f"内部状态: {bin(bf.bits)}")

案例九:取反运算的陷阱(易错点)

# Python的整数是无限精度的,~n = -n-1
print(~5)    # -6
print(~-5)   # 4

# 原理:按位取反,包括符号位
# 5  = ...00000101
# ~5 = ...11111010 = -6(补码表示)

# 如果需要固定8位取反(如图像处理)
definvert_8bit(n):
return (~n) &0xFF# 只保留低8位

print(invert_8bit(5))   # 250 (11111010)
print(invert_8bit(0))   # 255
print(invert_8bit(255)) # 0

📝 读者互动练习题

选择题(答案在评论区置顶):

  1. 15 & 9 的结果是?

    • A. 6  B. 9  C. 15  D. 0

  2. 如何用位运算判断一个数是4的倍数?

    • 提示:n & ? == 0

  3. ~0 在Python中的结果是?

    • A. 0  B. 1  C. -1  D. 255

编程挑战:

# 挑战1:不用算术运算符实现加法
defadd_without_plus(a, b):
# 提示:异或算无进位加法,与运算算进位
pass

# 挑战2:找出数组中唯一出现一次的数(其他都出现两次)
deffind_single(nums):
# 提示:利用 a ^ a = 0
pass

最新文章

随机文章