10个Python编程进阶技巧:从列表推导到切片优化
本文深入解析10个Python实用编程技巧,涵盖列表推导式简化代码、enumerate高效遍历、元组交换与解包、安全初始化列表、字符串格式化、字典访问优化、Counter库使用以及高级切片步进操作。帮助开发者写出更简洁、高效且符合Pythonic风格的代码,避免常见陷阱如浅拷贝和缩进错误。
列表推导式
假设你有一个列表变量 bag = [1, 2, 3, 4, 5]
现在,你的目标是将列表中的所有元素乘以2,期望得到的结果如 [2, 4, 6, 8, 10] 所示
许多初学者基于其他编程语言的惯性思维,通常会采用以下传统方式实现
bag = [1, 2, 3, 4, 5] for i in range(len(bag)): bag[i] = bag[i] * 2
然而,Python提供了更优雅的解决方案
bag = [elem * 2 for elem in bag]
这种写法是否更加简洁?这正是Python中强大的列表推导式(List Comprehension)
遍历列表
继续使用上述列表。在可能的情况下,应尽量避免以下这种低效的遍历方式
bag = [1, 2, 3, 4, 5] for i in range(len(bag)): print(bag[i])
推荐的替代方案如下所示
bag = [1, 2, 3, 4, 5] for i in bag: print(i)
如果 x 是一个列表,你可以直接迭代其元素。在大多数场景中,你并不需要元素的索引;但如果确实需要获取索引,可以使用 enumerate 函数,其用法如下
bag = [1, 2, 3, 4, 5] for index, element in enumerate(bag): print(index, element)
这种方式既直观又清晰
元素互换
如果你是从 Java 或 C 语言转向 Python 的开发者,可能习惯于使用临时变量进行交换,例如
a = 5 b = 10 # 交换 a 和 b tmp = a a = b b = tmp
但 Python 提供了一种更自然且简洁的语法糖
a = 5 b = 10 # 交换a 和 b a, b = b, a
初始化列表
假设你需要创建一个包含 10 个整数 0 的列表,你的第一反应可能是
bag = [] for _ in range(10): bag.append(0)
尝试换一种更简洁的写法
bag = [0] * 10
看起来更加优雅且高效
注意:如果列表中包含子列表,使用乘法初始化会产生浅拷贝(Shallow Copy)
请看以下示例
bag_of_bags = [[0]] * 5 # [[0], [0], [0], [0], [0]] bag_of_bags[0][0] = 1 # [[1], [1], [1], [1], [1]]
出现意外结果!所有子列表都发生了改变,而我们原本只想修改第一个子列表
修正方法如下
bag_of_bags = [[0] for _ in range(5)] # [[0], [0], [0], [0], [0]] bag_of_bags[0][0] = 1 # [[1], [0], [0], [0], [0]]
引用一句名言:“过早优化是万恶之源”。在初始化列表之前,请先自问:是否真的必须预先初始化?
构造字符串
在编程中,打印字符串是常见操作。当涉及多个变量时,应避免使用字符串拼接的方式
name = "Raymond" age = 22 born_in = "Oakland, CA" string = "Hello my name is " + name + "and I'm " + str(age) + " years old. I was born in " + born_in + "." print(string)
这种写法显得杂乱无章。你可以使用更简洁的 .format 方法作为替代
具体实现如下
name = "Raymond"
age = 22
born_in = "Oakland, CA"
string = "Hello my name is {0} and I'm {1} years old. I was born in {2}.".format(name, age, born_in)
print(string)
返回tuple元组
Python 允许函数返回多个元素,这简化了代码逻辑。但在解包元组时,常出现以下错误写法
def binary(): return 0, 1 result = binary() zero = result[0] one = result[1]
这是不必要的冗余操作,完全可以替换为更简洁的语法
def binary(): return 0, 1 zero, one = binary()
如果你需要忽略返回的部分元素,可以使用下划线 _ 作为占位符
zero, _ = binary()
这就是 Python 的高效之处
访问Dict字典
你经常需要向字典(dict)中写入键值对(key-value pairs)
如果你尝试访问字典中不存在的 key,为了避免 KeyError 异常,你可能会倾向于使用以下防御性编程方式
countr = {}
bag = [2, 3, 1, 2, 5, 6, 7, 9, 2, 7]
for i in bag:
if i in countr:
countr[i] += 1 else:
countr[i] = 1
for i in range(10):
if i in countr:
print("Count of {}: {}".format(i, countr[i]))
else:
print("Count of {}: {}".format(i, 0))
然而,使用 get() 方法是更优的选择
countr = {}
bag = [2, 3, 1, 2, 5, 6, 7, 9, 2, 7]
for i in bag:
countr[i] = countr.get(i, 0) + 1
for i in range(10):
print("Count of {}: {}".format(i, countr.get(i, 0)))
当然,你也可以使用 setdefault 方法来实现类似功能
这里还有一种更简单但开销较大的替代方案
bag = [2, 3, 1, 2, 5, 6, 7, 9, 2, 7]
# {2: 3, 3: 1, 1: 1, 5: 1, 6: 1, 7: 2, 9: 1}
countr = dict([(num, bag.count(num)) for num in bag])
for i in range(10):
print("Count of {}: {}".format(i, countr.get(i, 0)))
此外,你还可以使用字典推导式(Dictionary Comprehension)
countr = {num: bag.count(num) for num in bag}
这两种方法性能较差,因为每次调用 count 时都会遍历整个列表
使用库
利用现有的标准库或第三方库,只需导入即可实现核心功能
回到前面的例子,我们构建了一个函数来统计数字在列表中出现的次数。实际上,Python 标准库中已有现成的工具可以完成此任务
from collections import Counter
bag = [2, 3, 1, 2, 5, 6, 7, 9, 2, 7]
countr = Counter(bag)for i in range(10):
print("Count of {}: {}".format(i, countr[i]))
使用库的优势包括
• 代码经过充分测试,确保正确性。 • 算法通常经过优化,执行速度更快。 • 抽象化:接口明确且文档友好,让你能专注于业务逻辑而非底层实现。 • 最后,功能已现成可用,无需重复造轮子。 • 在列表中切片/步进
你可以指定起始点(start)和结束点(stop),语法格式为 list[start:stop:step]。例如,提取列表的前 5 个元素
bag = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] for elem in bag[:5]: print(elem)
这就是切片操作。我们指定 stop 参数为 5,因此在停止前会从列表中取出 5 个元素
如果需要提取最后 5 个元素,该如何操作?
bag = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] for elem in bag[-5:]: print(elem)
如果没看懂,-5 表示从列表末尾向前取 5 个元素
如果你想对列表中每隔一个元素进行操作,可能会尝试以下循环方式
bag = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] for index, elem in enumerate(bag): if index % 2 == 0: print(elem)
但你应该使用切片步进的方式来实现
bag = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] for elem in bag[::2]: print(elem) # 或者用 ranges bag = list(range(0,10,2)) print(bag)
这就是列表的步进(Step)操作。list[::2] 表示遍历时每两个元素取出一个
你可以使用 list[::-1] 来非常酷炫地翻转整个列表
Tab键还是空格
长期来看,混用 Tab 和空格会导致不必要的麻烦,你可能会遇到 IndentationError: unexpected indent 错误。无论选择 Tab 还是空格,应在整个文件和项目中保持一致
推荐使用空格而非 Tab 的原因之一是,Tab 在不同编辑器中的显示宽度不一致。根据所用编辑器,Tab 可能被解释为 2 到 8 个空格
你也可以在代码中使用空格来定义缩进层级。这样你可以自行决定用几个空格代表一个 Tab 层级。大多数 Python 用户约定使用 4 个空格
总结
以上介绍了 10 个值得掌握的 Python 编程小技巧,希望对大家有所帮助。如有任何疑问,欢迎留言交流,小编会及时回复。在此也非常感谢大家对本站的支持!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









