【转载】Python 老手也会犯的 20 个新手级错误(下)

204 阅读5分钟

英文原文链接20 Newbie Mistakes that Even Skilled Python Programmers Make | Avi_Chawla

中文译文链接Python 老手也会犯的 20 个新手级错误 | 王德朕

11. 使用 FOR 循环获取字符串的子串

新手写法

本次目标是从 start_index 位置开始,返回一个长度为 n_chars 的字符串子串。
新手解决这个问题的方法是使用 FOR 循环,如下所示:

input_str = "ABCDEFGHIJKL"  
start_index = 4  
n_chars = 5  
  
output_str = ""  
  
for i in range(n_chars):  
    output_str += input_str[i+start_index]  
  
print(output_str)  

优雅的写法

使用 切片,可以避免 FOR 循环。

input_str = "ABCDEFGHIJKL"  
start_index = 4  
n_chars = 5  
  
output_str = input_str[start_index:start_index+n_chars]  
print(output_str) 

12. 定义长整数常量

假设你想声明一个值为 102110^{21} 的整数变量。

新手写法

x = 1000000000000000000000 

理想情况下,人们会连续写 0,并在打字时进行计数,但如果有人想引用这个代码,他们数 0 难道不会很麻烦吗?

优雅的写法

为了提高可读性,可以用 _(下划线)分隔一组 0,如下所示:

x = 1_000_000_000_000_000_000_000

但这仍然是一个麻烦,为什么数 0
如果数字可以表示为 a^b 形式,那应该使用 pow() 方法。

x = pow(1021)

13. 用 IF 变换字符串大小写

给定一个字符串,目标使大写字母变成小写,反之亦然。

新手写法

简单的方法是检查每个元素的大小写,然后对每个字符都进行转换。

input_str = "AbCDeFGhIjkl"  
output_str = ""  
  
for i in input_str:  
  
    if i.islower():  
        output_str += i.upper()  
  
    elif i.isupper():  
        output_str += i.lower()  
      
    else:  
        output_str += i  
  
print(output_str) 

输出没有问题,但为什么要这么做?

优雅的写法

使用  swapcase () 方法

input_str = "AbCDeFGhIjkl"  
output_str = input_str.swapcase()  
  
print(output_str) 

14. 获取两个集合的并集

image.png 合并两个集合(图像由作者绘制)

新手写法

遍历这两个集合,将元素添加到一个新的集合中。

set_a = {1248}  
set_b = {38719}  
  
union_set = set()  
  
for i in set_a:  
    union_set.add(i)  
  
for i in set_b:  
    union_set.add(i)  
  
print(union_set) 

代码太多了,不是吗?让我们把它精简到一行。

优雅的写法

Python 中的集合为两个集合的合并提供了一个 union() 方法。

set_a = {1248}  
set_b = {38719}  
  
union_set = set_a.union(set_b)  
print(union_set)  

更重要的是,你可以将其扩展到 任意数量 的输入集合。

set_a = {1248}  
set_b = {38719}  
set_c = {591032}  
set_d = {7213150}  
  
union_set = set_a.union(set_b, set_c, set_d)  
print(union_set)

这很酷吧?想象一下,要合并 4 个集合,需要编写多少个 FOR 循环?

15. 获取两个集合的交集

新手写法

与上面讨论的合并情况类似,我们可以寻找两个集合之间的共同元素,如下所示:

set_a = {1248}  
set_b = {38719}  
  
intersection_set = set()  
  
for i in set_a:  
    if i in set_b:  
        intersection_set.add(i)  
  
print(intersection_set)  

优雅的写法

你可以使用 intersection() 方法实现同样的功能:

set_a = {1248}  
set_b = {38719}  
  
intersection_set = set_a.intersection(set_b)  
  
print(intersection_set)

16. 在 IF 语句中写多个条件

为了详细说明这一点,假设你想实现如下逻辑。

image.png 函数将输入映射到输出(图像由作者绘制)

新手写法

可以使用多个 or 分隔条件实现上述逻辑。

a = 1  
if a == 1 or a == 2 or a==3:  
    a += 1  
elif a == 4 or a == 5 or a==6:  
    a += 5  
else:  
    a *= 2  
print(a)  

优雅的写法

避免使用多个条件语句的方法是使用关键字 in,代码如下:

a = 1  
if a in (123):  
    a += 1  
elif a in (456):  
    a += 5  
else:  
    a *= 2  
print(a) 

17. 更改列表中所有元素的数据类型

给定一个表示整数的字符串列表,目标修改数据类型将其转换为整数列表。

新手写法

使用 FOR 循环和类型强制转换对单个元素进行变更。

优雅的写法

聪明的做法是使用 map() 函数,如下所示:

input_list = ["7""2""13""15""0"]  

output_list = list(map(int, input_list))  

print(output_list)  

map() 函数接收的第一个参数是转换函数(int),第二个参数是可迭代对象(input_list)。

18. 交换变量

给定两个变量,目标是对变量值进行交换。

新手写法

大多数 C/C++ 程序员在这里采取的方法是定义一个新的变量(temp),他们通常也会在 Python 中扩展这个方法。

a = "123"  
b = "abc"  
temp = a  

a = b  
b = temp  

print(a, b)  

优雅的写法

幸运的是,Python 允许在一个语句中进行 多次赋值,从而避免了对临时变量的需求。

a = "123"  

b = "abc"  

a, b = b, a  

print(a, b)  

19. 使用嵌套循环生成两个列表的所有组合

给定两个列表(a 的长度为 nb 的长度为 m),生成 (n*m)个组合。

新手写法

编写两个嵌套的 FOR 循环,并将所有组合追加到列表中。

list1 = ["A""B""C"]  
list2 = [12]  
combinations = []  

for i in list1:  
    for j in list2:  
        combinations.append([i, j])  

print(combinations)

优雅的写法

优雅的写法是使用 itertools 库中的 product() 方法,如下所示:

from itertools import product  

list1 = ["A""B""C"]  
list2 = [12]  
combinations = list(product(list1, list2))  

print(combinations)  

20. 结论

在这篇文章中,我展示了 20 种不同场景,我相信大多数 Python 程序员都经历过这些情况,而且可能也采取了错误的编码解决方案,如果你注意到,在大多数情况下,优雅的写法主要侧重于避免使用 FOR 循环进行编码
作为这篇文章的 重点,你应该永远记住,在大多数情况下,你想出的第一个解决方案并不是最优方案,因此,使用谷歌搜索总是有帮助的,这也是为什么 不完美主义的思维方式,对一名讲究的程序员非常重要的原因(不仅是 Python,其它语言也一样)。

更多

【转载】Python 老手也会犯的 20 个新手级错误(上)