Python 位运算和list用法详解

目录

概述

[1 位运算](#1 位运算)

[1.1 基本位运算符](#1.1 基本位运算符)

[1.2 位运算实用技巧](#1.2 位运算实用技巧)

[1.3 掩码操作](#1.3 掩码操作)

[1.4 位运算在算法中的应用](#1.4 位运算在算法中的应用)

[1.5 位运算性能优化示例](#1.5 位运算性能优化示例)

[1.6 注意事项](#1.6 注意事项)

[2 python list 用法](#2 python list 用法)

[2.1 创建列表](#2.1 创建列表)

[2.2 访问列表元素](#2.2 访问列表元素)

[2.3 修改列表](#2.3 修改列表)

[2.4 删除元素](#2.4 删除元素)

[2.5 列表方法](#2.5 列表方法)

[2.6 列表推导式](#2.6 列表推导式)

[2.7 列表操作技巧](#2.7 列表操作技巧)

[2.8 多维列表(嵌套列表)](#2.8 多维列表(嵌套列表))

[2.9 性能注意事项](#2.9 性能注意事项)

[2.10 实用示例](#2.10 实用示例)


概述

Python 提供了多种位运算操作符,这些操作符直接对整数的二进制位进行操作。列表(List)是 Python 中最常用的数据结构之一,它是一种有序、可变、可重复的集合。列表是 Python 中最灵活、最强大的数据结构之一。掌握列表的各种用法对于编写高效、简洁的 Python 代码至关重要。

1 位运算

位运算在Python中是非常强大的工具,尤其在以下场景中特别有用:

  • 处理二进制数据

  • 优化性能关键代码

  • 实现某些算法(如位掩码、状态压缩)

  • 与硬件交互或处理底层数据

掌握位运算可以帮助你编写更高效、更简洁的代码,特别是在处理大量数据或性能敏感的应用中。

1.1 基本位运算符

python 复制代码
# 基本示例
a = 10  # 二进制: 1010
b = 4   # 二进制: 0100

print(f"a = {a} (二进制: {bin(a)})")
print(f"b = {b} (二进制: {bin(b)})")

# 1. 按位与 (&) - 两个位都为1时,结果才为1
print(f"a & b = {a & b} (二进制: {bin(a & b)})")  # 1010 & 0100 = 0000 (0)

# 2. 按位或 (|) - 两个位有一个为1时,结果就为1
print(f"a | b = {a | b} (二进制: {bin(a | b)})")  # 1010 | 0100 = 1110 (14)

# 3. 按位异或 (^) - 两个位不同时,结果为1
print(f"a ^ b = {a ^ b} (二进制: {bin(a ^ b)})")  # 1010 ^ 0100 = 1110 (14)

# 4. 按位取反 (~) - 每个位取反
print(f"~a = {~a} (二进制: {bin(~a & 0b1111)})")  # ~1010 = 0101 (5) 但需要注意Python的补码表示

# 5. 左移 (<<) - 所有位向左移动,右侧补0
print(f"a << 2 = {a << 2} (二进制: {bin(a << 2)})")  # 1010 << 2 = 101000 (40)

# 6. 右移 (>>) - 所有位向右移动,左侧补0(对正整数)
print(f"a >> 1 = {a >> 1} (二进制: {bin(a >> 1)})")  # 1010 >> 1 = 0101 (5)

1.2 位运算实用技巧

python 复制代码
# 1. 检查奇偶性
def is_even(n):
    return (n & 1) == 0

print(f"5是偶数吗?{is_even(5)}")  # False
print(f"8是偶数吗?{is_even(8)}")  # True

# 2. 检查是否是2的幂
def is_power_of_two(n):
    return n > 0 and (n & (n - 1)) == 0

print(f"8是2的幂吗?{is_power_of_two(8)}")  # True
print(f"10是2的幂吗?{is_power_of_two(10)}")  # False

# 3. 交换两个数的值(不使用临时变量)
x, y = 5, 9
print(f"交换前: x={x}, y={y}")
x ^= y
y ^= x
x ^= y
print(f"交换后: x={x}, y={y}")

# 4. 获取最低位的1
def get_lowest_set_bit(n):
    return n & -n

print(f"12的最低位的1: {get_lowest_set_bit(12)} (二进制: {bin(get_lowest_set_bit(12))})")

# 5. 移除最低位的1
def clear_lowest_set_bit(n):
    return n & (n - 1)

print(f"移除12的最低位的1: {clear_lowest_set_bit(12)} (二进制: {bin(clear_lowest_set_bit(12))})")

# 6. 统计二进制中1的个数
def count_set_bits(n):
    count = 0
    while n:
        n &= (n - 1)  # 每次移除最低位的1
        count += 1
    return count

print(f"12的二进制中1的个数: {count_set_bits(12)}")

# Python内置方法
print(f"Python内置方法统计12的二进制中1的个数: {bin(12).count('1')}")

1.3 掩码操作

python 复制代码
# 使用掩码操作特定位

# 1. 设置某一位为1
def set_bit(n, pos):
    return n | (1 << pos)

num = 0b1010  # 10
print(f"将第1位设置为1: {bin(set_bit(num, 1))}")  # 0b1010 -> 0b1010 | 0b0010 = 0b1010 (不变)
print(f"将第2位设置为1: {bin(set_bit(num, 2))}")  # 0b1010 -> 0b1010 | 0b0100 = 0b1110 (14)

# 2. 清除某一位(设置为0)
def clear_bit(n, pos):
    return n & ~(1 << pos)

print(f"清除第1位: {bin(clear_bit(num, 1))}")  # 0b1010 & ~0b0010 = 0b1010 & 0b1101 = 0b1000 (8)

# 3. 切换某一位(0变1,1变0)
def toggle_bit(n, pos):
    return n ^ (1 << pos)

print(f"切换第1位: {bin(toggle_bit(num, 1))}")  # 0b1010 ^ 0b0010 = 0b1000 (8)
print(f"切换第2位: {bin(toggle_bit(num, 2))}")  # 0b1010 ^ 0b0100 = 0b1110 (14)

# 4. 检查某一位是否为1
def check_bit(n, pos):
    return (n & (1 << pos)) != 0

print(f"第1位是1吗?{check_bit(num, 1)}")  # True (0b1010 & 0b0010 = 0b0010 ≠ 0)
print(f"第2位是1吗?{check_bit(num, 2)}")  # False (0b1010 & 0b0100 = 0)

# 5. 提取多个位
def extract_bits(n, start, length):
    mask = (1 << length) - 1
    return (n >> start) & mask

num = 0b11011010  # 218
print(f"提取第2-5位: {bin(extract_bits(num, 2, 4))}")  # 0b1101

1.4 位运算在算法中的应用

python 复制代码
# 1. 只出现一次的数字(其他数字都出现两次)
def single_number(nums):
    result = 0
    for num in nums:
        result ^= num
    return result

print(f"只出现一次的数字: {single_number([4, 1, 2, 1, 2])}")  # 4

# 2. 子集生成(使用位掩码)
def generate_subsets(nums):
    n = len(nums)
    subsets = []
    for mask in range(1 << n):  # 2^n 种可能
        subset = []
        for i in range(n):
            if mask & (1 << i):  # 检查第i位是否为1
                subset.append(nums[i])
        subsets.append(subset)
    return subsets

nums = [1, 2, 3]
subsets = generate_subsets(nums)
print(f"{nums}的所有子集:")
for subset in subsets:
    print(subset)

# 3. 计算两个整数的和(不使用+和-)
def add_without_operator(a, b):
    while b != 0:
        carry = a & b  # 计算进位
        a = a ^ b      # 计算无进位和
        b = carry << 1  # 进位左移
    return a

print(f"5 + 7 = {add_without_operator(5, 7)}")

1.5 位运算性能优化示例

python 复制代码
import time

# 比较乘除2的运算速度
def test_performance():
    n = 10000000
    start = time.time()
    
    # 使用算术运算
    result1 = 0
    for i in range(n):
        result1 = i * 2
        
    mid = time.time()
    
    # 使用位运算
    result2 = 0
    for i in range(n):
        result2 = i << 1
        
    end = time.time()
    
    print(f"算术运算时间: {mid - start:.6f}秒")
    print(f"位运算时间: {end - mid:.6f}秒")
    print(f"时间差: {(mid - start) - (end - mid):.6f}秒")

# test_performance()

1.6 注意事项

python 复制代码
# 1. Python中整数的位数是动态的,没有固定位数限制
large_num = 1 << 1000
print(f"1 << 1000 的位数: {large_num.bit_length()}")

# 2. 处理负数时需要注意
negative_num = -10
print(f"-10 的二进制表示: {bin(negative_num)}")
print(f"-10 >> 1 = {-10 >> 1} (二进制: {bin(-10 >> 1)})")

# 3. 与0xFF等掩码配合使用可以限制位数
value = 300
print(f"300的16位表示: {value & 0xFFFF} (二进制: {bin(value & 0xFFFF)})")

2 python list 用法

2.1 创建列表

python 复制代码
# 1. 空列表
empty_list = []
empty_list2 = list()

# 2. 包含元素的列表
numbers = [1, 2, 3, 4, 5]
fruits = ['apple', 'banana', 'cherry']
mixed = [1, 'hello', 3.14, True]

# 3. 使用 list() 构造函数
list_from_string = list('hello')  # ['h', 'e', 'l', 'l', 'o']
list_from_range = list(range(5))  # [0, 1, 2, 3, 4]
list_from_tuple = list((1, 2, 3))  # [1, 2, 3]

# 4. 列表推导式
squares = [x**2 for x in range(10)]  # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
even_numbers = [x for x in range(20) if x % 2 == 0]  # [0, 2, 4, ..., 18]

print("创建的各种列表:")
print(f"numbers: {numbers}")
print(f"fruits: {fruits}")
print(f"mixed: {mixed}")
print(f"list_from_string: {list_from_string}")
print(f"squares: {squares}")

2.2 访问列表元素

python 复制代码
# 创建示例列表
fruits = ['apple', 'banana', 'cherry', 'date', 'elderberry']

# 1. 索引访问(从0开始)
print(fruits[0])      # apple
print(fruits[2])      # cherry

# 2. 负数索引(从末尾开始)
print(fruits[-1])     # elderberry
print(fruits[-2])     # date

# 3. 切片访问 [start:end:step]
print(fruits[1:3])    # ['banana', 'cherry']   # 包含1,不包含3
print(fruits[:3])     # ['apple', 'banana', 'cherry']  # 从头开始
print(fruits[2:])     # ['cherry', 'date', 'elderberry']  # 到末尾
print(fruits[::2])    # ['apple', 'cherry', 'elderberry']  # 每隔一个
print(fruits[::-1])   # 反转列表

# 4. 长度
print(len(fruits))    # 5

# 5. 检查元素是否存在
print('banana' in fruits)    # True
print('grape' in fruits)     # False

# 6. 遍历列表
print("遍历列表:")
for fruit in fruits:
    print(fruit)

print("带索引遍历:")
for index, fruit in enumerate(fruits):
    print(f"{index}: {fruit}")

print("反向遍历:")
for fruit in reversed(fruits):
    print(fruit)

2.3 修改列表

python 复制代码
fruits = ['apple', 'banana', 'cherry']

# 1. 修改单个元素
fruits[1] = 'blueberry'
print(f"修改后: {fruits}")  # ['apple', 'blueberry', 'cherry']

# 2. 修改多个元素(切片赋值)
fruits[1:3] = ['blackberry', 'cantaloupe']
print(f"切片修改后: {fruits}")  # ['apple', 'blackberry', 'cantaloupe']

# 3. 添加元素
fruits.append('date')          # 末尾添加
print(f"append 后: {fruits}")  # ['apple', 'blackberry', 'cantaloupe', 'date']

fruits.insert(1, 'apricot')    # 在指定位置插入
print(f"insert 后: {fruits}")  # ['apple', 'apricot', 'blackberry', 'cantaloupe', 'date']

# 4. 扩展列表
more_fruits = ['elderberry', 'fig']
fruits.extend(more_fruits)     # 添加多个元素
print(f"extend 后: {fruits}")

# 也可以使用 + 或 +=
fruits += ['grape', 'honeydew']
print(f"+= 后: {fruits}")

2.4 删除元素

python 复制代码
fruits = ['apple', 'banana', 'cherry', 'date', 'elderberry', 'fig', 'grape']

# 1. del 语句
del fruits[1]                    # 删除索引为1的元素
print(f"del 后: {fruits}")      # ['apple', 'cherry', 'date', 'elderberry', 'fig', 'grape']

del fruits[2:4]                  # 删除切片
print(f"del 切片后: {fruits}")  # ['apple', 'cherry', 'fig', 'grape']

# 2. pop() - 删除并返回指定位置的元素
popped = fruits.pop()            # 默认删除最后一个
print(f"pop() 后: {fruits}, 弹出的元素: {popped}")

popped = fruits.pop(1)           # 删除指定位置
print(f"pop(1) 后: {fruits}, 弹出的元素: {popped}")

# 3. remove() - 删除第一个匹配的元素
fruits.remove('apple')
print(f"remove('apple') 后: {fruits}")

# 4. clear() - 清空列表
fruits.clear()
print(f"clear() 后: {fruits}")  # []

2.5 列表方法

python 复制代码
numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]

# 1. count() - 统计元素出现次数
print(f"5出现的次数: {numbers.count(5)}")  # 3

# 2. index() - 查找元素首次出现的索引
print(f"第一个5的索引: {numbers.index(5)}")  # 4
print(f"从索引6开始找5: {numbers.index(5, 6)}")  # 9

# 3. sort() - 原地排序
numbers.sort()
print(f"升序排序: {numbers}")

numbers.sort(reverse=True)
print(f"降序排序: {numbers}")

# 4. sorted() - 返回新排序列表(不改变原列表)
unsorted = [3, 1, 4, 1, 5]
sorted_list = sorted(unsorted)
print(f"原列表: {unsorted}")
print(f"排序后新列表: {sorted_list}")

# 5. reverse() - 原地反转
numbers.reverse()
print(f"反转后: {numbers}")

# 6. copy() - 浅拷贝
original = [1, 2, [3, 4]]
copied = original.copy()
original[2][0] = 99
print(f"浅拷贝: 原列表 {original}, 拷贝列表 {copied}")  # 注意嵌套列表被共享

# 7. 深拷贝
import copy
deep_copied = copy.deepcopy(original)
original[2][1] = 100
print(f"深拷贝: 原列表 {original}, 深拷贝列表 {deep_copied}")

2.6 列表推导式

python 复制代码
# 1. 基本推导式
squares = [x**2 for x in range(10)]
print(f"平方数: {squares}")

# 2. 带条件的推导式
even_squares = [x**2 for x in range(10) if x % 2 == 0]
print(f"偶数的平方: {even_squares}")

# 3. 嵌套循环推导式
pairs = [(x, y) for x in range(3) for y in range(3)]
print(f"坐标对: {pairs}")

# 4. 嵌套列表推导式(矩阵转置)
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
transposed = [[row[i] for row in matrix] for i in range(3)]
print(f"矩阵转置: {transposed}")

# 5. 条件表达式(类似三元表达式)
labels = ['偶数' if x % 2 == 0 else '奇数' for x in range(10)]
print(f"奇偶标签: {labels}")

# 6. 嵌套推导式展平列表
nested = [[1, 2, 3], [4, 5], [6, 7, 8, 9]]
flattened = [item for sublist in nested for item in sublist]
print(f"展平嵌套列表: {flattened}")

2.7 列表操作技巧

python 复制代码
# 1. 列表拼接
list1 = [1, 2, 3]
list2 = [4, 5, 6]
combined = list1 + list2
print(f"列表拼接: {combined}")

# 2. 重复列表
repeated = [1, 2] * 3
print(f"列表重复: {repeated}")

# 3. 解包列表
first, *middle, last = [1, 2, 3, 4, 5]
print(f"first: {first}, middle: {middle}, last: {last}")

# 4. 列表比较(按元素逐个比较)
print([1, 2, 3] < [1, 2, 4])  # True
print([1, 2, 3] < [1, 2])     # False

# 5. 过滤列表
numbers = [1, 2, 3, 4, 5, 6]
filtered = list(filter(lambda x: x % 2 == 0, numbers))
print(f"过滤偶数: {filtered}")

# 6. 映射列表
mapped = list(map(lambda x: x * 2, numbers))
print(f"映射加倍: {mapped}")

# 7. zip多个列表
names = ['Alice', 'Bob', 'Charlie']
ages = [25, 30, 35]
for name, age in zip(names, ages):
    print(f"{name} is {age} years old")

# 8. 使用any()和all()
print(any(x > 5 for x in [1, 3, 5, 7]))  # True
print(all(x > 5 for x in [1, 3, 5, 7]))  # False

2.8 多维列表(嵌套列表)

python 复制代码
# 1. 创建二维列表(矩阵)
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

# 2. 访问元素
print(f"矩阵[1][2]: {matrix[1][2]}")  # 6

# 3. 遍历二维列表
print("逐行遍历:")
for row in matrix:
    print(row)

print("逐个元素遍历:")
for row in matrix:
    for element in row:
        print(element, end=' ')
    print()

# 4. 列表推导式创建二维列表
matrix_5x5 = [[0 for _ in range(5)] for _ in range(5)]
print(f"5x5零矩阵: {matrix_5x5}")

# 5. 注意事项:错误的方式创建多维列表
wrong_matrix = [[0] * 5] * 3  # 这种方式会创建共享的引用
wrong_matrix[0][0] = 1
print(f"错误的多维列表创建: {wrong_matrix}")  # 所有行的第一列都变成了1

2.9 性能注意事项

python 复制代码
import time

# 1. append() vs insert(0)
def test_performance():
    n = 10000
    
    # 在末尾添加元素 - O(1)
    start = time.time()
    lst = []
    for i in range(n):
        lst.append(i)
    end = time.time()
    print(f"append() 耗时: {end-start:.6f}秒")
    
    # 在开头插入元素 - O(n)
    start = time.time()
    lst = []
    for i in range(n):
        lst.insert(0, i)
    end = time.time()
    print(f"insert(0) 耗时: {end-start:.6f}秒")

test_performance()

# 2. 成员检查性能比较
def membership_test():
    lst = list(range(10000))
    s = set(range(10000))
    
    # 列表查找 - O(n)
    start = time.time()
    print(9999 in lst)  # 最坏情况
    end = time.time()
    print(f"列表成员检查耗时: {end-start:.6f}秒")
    
    # 集合查找 - O(1)
    start = time.time()
    print(9999 in s)
    end = time.time()
    print(f"集合成员检查耗时: {end-start:.6f}秒")

membership_test()

2.10 实用示例

python 复制代码
# 1. 去重(保持顺序)
def deduplicate(lst):
    seen = set()
    result = []
    for item in lst:
        if item not in seen:
            seen.add(item)
            result.append(item)
    return result

numbers = [1, 2, 2, 3, 4, 4, 5, 1, 2]
print(f"去重后: {deduplicate(numbers)}")

# 2. 统计频率
def frequency_counter(lst):
    freq = {}
    for item in lst:
        freq[item] = freq.get(item, 0) + 1
    return freq

words = ['apple', 'banana', 'apple', 'cherry', 'banana', 'apple']
print(f"频率统计: {frequency_counter(words)}")

# 3. 列表分块
def chunk_list(lst, chunk_size):
    return [lst[i:i+chunk_size] for i in range(0, len(lst), chunk_size)]

numbers = list(range(10))
print(f"分块 (大小3): {chunk_list(numbers, 3)}")

# 4. 列表旋转
def rotate_list(lst, k):
    k = k % len(lst)  # 处理k大于列表长度的情况
    return lst[-k:] + lst[:-k]

print(f"旋转列表 [1,2,3,4,5] (k=2): {rotate_list([1,2,3,4,5], 2)}")
相关推荐
Lary_c2 小时前
Selenium Webdriver 元素等待方式详解
python·selenium·测试工具·自动化
熊文豪2 小时前
完整卸载 OpenClaw — 各平台卸载完全指南(Windows/macOS/Linux/npm/pnpm)
linux·windows·macos·openclaw
geovindu2 小时前
python: Builder Pattern
python·设计模式·建造者模式
不懒不懒2 小时前
【零基础入门 PyTorch:实现食物图片分类任务】
人工智能·pytorch·python
喵手2 小时前
Python爬虫实战:从天气抓取到机器学习预测气温!
爬虫·python·机器学习·爬虫实战·预测气温·零基础python爬虫教学·天气采集
猿饵块2 小时前
python--sys
开发语言·python
智能工业品检测-奇妙智能2 小时前
linux 安装 FFmpeg 和windows安装 FFmpeg
linux·windows·ffmpeg
故河2 小时前
Python工具:Conda 包管理器
开发语言·python·conda
Dontla2 小时前
安装Miniconda安装(Windows)、conda虚拟环境创建、conda虚拟环境激活
windows·python