Python list花式用法集锦

3 阅读9分钟

Python list花式用法集锦


一、切片的花式玩法

1. 反转列表

lst = [1, 2, 3, 4, 5]
print(lst[::-1])   # [5, 4, 3, 2, 1]

2. 隔一个取一个

lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(lst[::2])    # [0, 2, 4, 6, 8]
print(lst[1::2])   # [1, 3, 5, 7, 9]

3. 用切片赋值实现“原地替换”

lst = [1, 2, 3, 4, 5]
lst[1:4] = [20, 30]      # 长度可以变
print(lst)               # [1, 20, 30, 5]

4. 用切片删除一段

lst = [1, 2, 3, 4, 5]
del lst[1:4]
print(lst)               # [1, 5]

5. 用切片清空但保留引用

lst = [1, 2, 3]
lst[:] = []              # 原地清空,其他引用这个列表的变量也会看到空
print(lst)               # []

lst = [] 的区别

a = [1, 2, 3]
b = a
a = []          # a 指向新列表,b 还是 [1, 2, 3]
print(b)        # [1, 2, 3]

a = [1, 2, 3]
b = a
a[:] = []       # 原地清空,a 和 b 都变空
print(b)        # []

6. 用切片复制

lst = [1, 2, 3]
copy1 = lst[:]           # 浅拷贝
copy2 = lst.copy()
copy3 = list(lst)

二、列表推导式的花式玩法

1. 条件表达式(三元)

nums = [1, 2, 3, 4, 5]
result = [x**2 if x % 2 == 0 else -x for x in nums]
print(result)   # [-1, 4, -3, 16, -5]

2. 多层嵌套

matrix = [[1, 2], [3, 4], [5, 6]]
flat = [x for row in matrix for x in row]
print(flat)     # [1, 2, 3, 4, 5, 6]

3. 多个条件

nums = [x for x in range(30) if x % 2 == 0 if x % 3 == 0]
print(nums)     # [0, 6, 12, 18, 24]

4. 生成笛卡尔积

colors = ["红", "绿"]
sizes = ["S", "M", "L"]
combos = [(c, s) for c in colors for s in sizes]
print(combos)
# [('红', 'S'), ('红', 'M'), ('红', 'L'), ('绿', 'S'), ('绿', 'M'), ('绿', 'L')]

5. 转置矩阵

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
transposed = [[row[i] for row in matrix] for i in range(3)]
print(transposed)   # [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

6. 用 zip(*matrix) 转置

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
transposed = [list(row) for row in zip(*matrix)]
print(transposed)   # [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

zip(*matrix) 是转置的经典技巧* 把矩阵解包成多个参数。

7. 条件筛选 + 去重

nums = [1, 1, 2, 2, 3, 3, 4]
unique_evens = list(dict.fromkeys(x for x in nums if x % 2 == 0))
print(unique_evens)   # [2, 4]

三、zipenumerate 的花式玩法

1. zip 转字典

keys = ["name", "age", "city"]
values = ["小明", 25, "北京"]
d = dict(zip(keys, values))
print(d)   # {'name': '小明', 'age': 25, 'city': '北京'}

2. zip 解压

pairs = [("小明", 25), ("小红", 30), ("小刚", 28)]
names, ages = zip(*pairs)
print(names)   # ('小明', '小红', '小刚')
print(ages)    # (25, 30, 28)

3. enumerate 配合字典

fruits = ["apple", "banana", "cherry"]
d = {i: fruit for i, fruit in enumerate(fruits)}
print(d)   # {0: 'apple', 1: 'banana', 2: 'cherry'}

# 反过来:值作键,索引作值
d = {fruit: i for i, fruit in enumerate(fruits)}
print(d)   # {'apple': 0, 'banana': 1, 'cherry': 2}

4. zip 找共同元素

a = [1, 2, 3]
b = [2, 3, 4]
common = [x for x, y in zip(a, b) if x == y]
print(common)   # [2, 3]

5. zip 两两配对

lst = [1, 2, 3, 4, 5, 6]
pairs = list(zip(lst[::2], lst[1::2]))
print(pairs)   # [(1, 2), (3, 4), (5, 6)]

6. 滑动窗口

lst = [1, 2, 3, 4, 5]
windows = list(zip(lst, lst[1:], lst[2:]))
print(windows)   # [(1, 2, 3), (2, 3, 4), (3, 4, 5)]

这是滑动窗口的经典写法,比手动索引简洁。


四、列表解包的花式玩法

1. 星号解包

first, *rest = [1, 2, 3, 4, 5]
print(first)   # 1
print(rest)    # [2, 3, 4, 5]

*init, last = [1, 2, 3, 4, 5]
print(init)    # [1, 2, 3, 4]
print(last)    # 5

a, *mid, b = [1, 2, 3, 4, 5]
print(a, mid, b)   # 1 [2, 3, 4] 5

2. 合并列表

a = [1, 2]
b = [3, 4]
c = [*a, *b]
print(c)   # [1, 2, 3, 4]

# 合并多个
lists = [[1], [2], [3]]
merged = [*lists[0], *lists[1], *lists[2]]
print(merged)   # [1, 2, 3]

3. 解包传参

def add(a, b, c):
    return a + b + c

nums = [1, 2, 3]
print(add(*nums))   # 6

4. 解包转置

matrix = [[1, 2], [3, 4], [5, 6]]
transposed = list(zip(*matrix))
print(transposed)   # [(1, 3, 5), (2, 4, 6)]

五、列表作为栈和队列的花式用法

1. 栈(后进先出)

stack = []
stack.append(1)
stack.append(2)
stack.append(3)
print(stack.pop())   # 3
print(stack.pop())   # 2

2. 用列表实现队列(不推荐)

queue = []
queue.append(1)
queue.append(2)
print(queue.pop(0))   # 1,O(n)

3. 用 deque 实现队列(推荐)

from collections import deque

queue = deque()
queue.append(1)
queue.append(2)
print(queue.popleft())   # 1,O(1)

4. 用列表模拟固定大小缓冲区

buffer = []
max_size = 3

def add(x):
    if len(buffer) >= max_size:
        buffer.pop(0)   # 删最旧的
    buffer.append(x)

add(1); add(2); add(3); add(4)
print(buffer)   # [2, 3, 4]

更高效用 deque(maxlen=3)

from collections import deque
buffer = deque(maxlen=3)
buffer.append(1); buffer.append(2); buffer.append(3); buffer.append(4)
print(buffer)   # deque([2, 3, 4], maxlen=3)

六、列表和字符串互转的花式用法

1. 字符串转列表

s = "hello"
lst = list(s)          # ['h', 'e', 'l', 'l', 'o']
lst = s.split()        # 按空白切
lst = s.split(",")     # 按逗号切

2. 列表转字符串

words = ["hello", "world"]
s = " ".join(words)    # "hello world"
s = ",".join(words)    # "hello,world"
s = "".join(words)     # "helloworld"

3. 数字列表转字符串

nums = [1, 2, 3]
s = "".join(map(str, nums))   # "123"
s = ",".join(str(x) for x in nums)   # "1,2,3"

4. 字符串反转

s = "hello"
reversed_s = "".join(reversed(s))   # "olleh"
reversed_s = s[::-1]                # "olleh"

5. 列表元素反转

lst = ["a", "b", "c"]
reversed_lst = lst[::-1]            # ['c', 'b', 'a']
reversed_lst = list(reversed(lst))  # ['c', 'b', 'a']

七、列表的统计和聚合

1. 求和、最大、最小

nums = [1, 2, 3, 4, 5]
print(sum(nums))    # 15
print(max(nums))    # 5
print(min(nums))    # 1
print(len(nums))    # 5

2. 平均值

avg = sum(nums) / len(nums)   # 3.0

3. 统计元素频率

from collections import Counter

lst = [1, 1, 2, 3, 3, 3]
counter = Counter(lst)
print(counter)              # Counter({3: 3, 1: 2, 2: 1})
print(counter.most_common(2))   # [(3, 3), (1, 2)]

4. 用字典手动统计

lst = [1, 1, 2, 3, 3, 3]
freq = {}
for x in lst:
    freq[x] = freq.get(x, 0) + 1
print(freq)   # {1: 2, 2: 1, 3: 3}

5. allany

nums = [1, 2, 3, 4, 5]
print(all(x > 0 for x in nums))   # True,全部大于 0
print(any(x > 4 for x in nums))   # True,存在大于 4

# 判断列表是否全为真
print(all(nums))   # True
print(all([1, 0, 2]))   # False,有 0

6. 列表元素累加

import itertools

nums = [1, 2, 3, 4, 5]
acc = list(itertools.accumulate(nums))
print(acc)   # [1, 3, 6, 10, 15]

八、列表的排序花式用法

1. 按绝对值排序

nums = [-3, 1, -2, 4]
nums.sort(key=abs)
print(nums)   # [1, -2, -3, 4]

2. 按字符串长度排序

words = ["apple", "hi", "banana"]
words.sort(key=len)
print(words)   # ['hi', 'apple', 'banana']

3. 按多个条件排序

students = [("小明", 25), ("小红", 20), ("小刚", 25)]
students.sort(key=lambda x: (x[1], x[0]))
print(students)
# [('小红', 20), ('小刚', 25), ('小明', 25)]

4. 自定义比较函数

from functools import cmp_to_key

def compare(a, b):
    if a > b:
        return -1
    elif a < b:
        return 1
    return 0

nums = [3, 1, 4, 1, 5]
nums.sort(key=cmp_to_key(compare))
print(nums)   # [5, 4, 3, 1, 1],降序

5. 稳定排序

Python 的 sort稳定排序,相同 key 的元素保持原顺序。

data = [("A", 2), ("B", 1), ("C", 2), ("D", 1)]
data.sort(key=lambda x: x[1])
print(data)
# [('B', 1), ('D', 1), ('A', 2), ('C', 2)]
# 同 key 的 B 在 D 前,A 在 C 前,保持原顺序

6. 排序后取 Top K

nums = [3, 1, 4, 1, 5, 9, 2, 6]
top3 = sorted(nums, reverse=True)[:3]
print(top3)   # [9, 6, 5]

# 更高效:heapq.nlargest
import heapq
top3 = heapq.nlargest(3, nums)
print(top3)   # [9, 6, 5]

九、列表的查找和判断

1. 找第一个满足条件的元素

nums = [1, 2, 3, 4, 5]
first_even = next((x for x in nums if x % 2 == 0), None)
print(first_even)   # 2

next(生成器, 默认值)找第一个匹配项的经典写法,找不到返回默认值。

2. 找所有满足条件的元素

evens = [x for x in nums if x % 2 == 0]
print(evens)   # [2, 4]

3. 判断是否包含

print(3 in nums)       # True
print(10 not in nums)  # True

4. 找最大/最小的索引

nums = [3, 1, 4, 1, 5]
max_idx = nums.index(max(nums))
min_idx = nums.index(min(nums))
print(max_idx, min_idx)   # 4 1

5. 找所有匹配的索引

nums = [1, 2, 3, 2, 4, 2]
indices = [i for i, x in enumerate(nums) if x == 2]
print(indices)   # [1, 3, 5]

6. 二分查找

import bisect

nums = [1, 3, 5, 7, 9]
print(bisect.bisect_left(nums, 5))    # 2,第一个 >= 5 的位置
print(bisect.bisect_right(nums, 5))   # 3,第一个 > 5 的位置

# 插入并保持有序
bisect.insort(nums, 4)
print(nums)   # [1, 3, 4, 5, 7, 9]

十、列表的“黑魔法”

1. 用 * 解包合并

a = [1, 2]
b = [3, 4]
c = [*a, *b, 5]
print(c)   # [1, 2, 3, 4, 5]

2. 用 ++= 的区别

a = [1, 2]
b = a
a += [3]        # 原地修改,a 和 b 都变 [1, 2, 3]
print(b)        # [1, 2, 3]

a = [1, 2]
b = a
a = a + [3]     # 创建新列表,b 还是 [1, 2]
print(b)        # [1, 2]

+= 是原地修改,+ 是创建新列表。

3. 列表的 id 和引用

a = [1, 2, 3]
b = a
print(id(a) == id(b))   # True,同一对象

b = a[:]
print(id(a) == id(b))   # False,不同对象

4. 用列表推导式做“副作用”

# ❌ 不推荐,但能用
[print(x) for x in range(3)]
# 输出 0 1 2,同时生成 [None, None, None]

# ✅ 正确做法
for x in range(3):
    print(x)

5. 用 list__contains__ 做自定义判断

class MyList(list):
    def __contains__(self, item):
        return item in [x * 2 for x in self]

lst = MyList([1, 2, 3])
print(2 in lst)   # False,因为列表里没有 4
print(4 in lst)   # True,因为 2*2=4

6. 用列表模拟矩阵运算

# 矩阵加法
a = [[1, 2], [3, 4]]
b = [[5, 6], [7, 8]]
result = [[a[i][j] + b[i][j] for j in range(2)] for i in range(2)]
print(result)   # [[6, 8], [10, 12]]

# 矩阵乘法
a = [[1, 2], [3, 4]]
b = [[5, 6], [7, 8]]
result = [[sum(a[i][k] * b[k][j] for k in range(2)) for j in range(2)] for i in range(2)]
print(result)   # [[19, 22], [43, 50]]

7. 用 zip 实现“分组”

lst = [1, 2, 3, 4, 5, 6, 7, 8]
n = 3
groups = [lst[i:i+n] for i in range(0, len(lst), n)]
print(groups)   # [[1, 2, 3], [4, 5, 6], [7, 8]]

8. 用 itertools 做分组

import itertools

lst = [1, 2, 3, 4, 5, 6, 7, 8]
n = 3
groups = list(itertools.zip_longest(*[iter(lst)] * n))
print(groups)   # [(1, 2, 3), (4, 5, 6), (7, 8, None)]

9. 用列表推导式做“展平一层”

nested = [[1, 2], [3, [4, 5]], [6]]
flat = [x for sub in nested for x in (sub if isinstance(sub, list) else [sub])]
print(flat)   # [1, 2, 3, [4, 5], 6],只展平一层

10. 用 sum 展平列表

nested = [[1, 2], [3, 4], [5, 6]]
flat = sum(nested, [])
print(flat)   # [1, 2, 3, 4, 5, 6]

注意:这种写法是 O(n²),只适合小列表。大列表用 itertools.chain


十一、花式用法 vs 可读性

花式用法虽然巧妙,但可读性往往下降。选择原则:

场景推荐
简单转换列表推导式
复杂逻辑普通 for 循环
找第一个匹配next((x for x in ...), default)
展平列表itertools.chain
转置矩阵zip(*matrix)
去重保序dict.fromkeys
统计频率Counter
Top Kheapq.nlargest
滑动窗口zip(lst, lst[1:], ...)

原则花式用法是工具,不是目的。能用简单写法就别炫技。 团队协作中,可读性 > 简洁性。


十二、一句话总结

花式用法写法
反转lst[::-1]
隔一个取lst[::2]
原地清空lst[:] = []
展平[x for sub in nested for x in sub]
转置zip(*matrix)
解包a, *rest = lst
合并[*a, *b]
转字典dict(zip(keys, values))
反转字典{v: k for k, v in d.items()}
找第一个next((x for x in lst if ...), None)
去重保序list(dict.fromkeys(lst))
滑动窗口zip(lst, lst[1:], lst[2:])
分组[lst[i:i+n] for i in range(0, len(lst), n)]
Top Kheapq.nlargest(k, lst)
累加itertools.accumulate(lst)
频率Counter(lst)
二分查找bisect.bisect_left/right

核心记住:list 的花式用法大多围绕切片、推导式、zip、解包、itertools 展开。它们能让代码更简洁,但可读性优先,别为了炫技而用。