【转载】惯用 Python 的 5 个技巧(循环)

161 阅读5分钟

原文链接

惯用Python的5个技巧(循环)

正文

在这篇文章中,你将看到 5 种方法可以使你的 Python 循环更习惯,运行得更快,内存效率更高。

图片

在我看来,Python 是计算机科学中最简单、最通用的语言之一。如果你正确地编写 Python 代码,很难区分 Python 代码和伪代码。但有时,在编写最漂亮的 Python 代码的过程中,大多数开发人员会忘记一件事: 代码的执行速度。

您可以编写可读性非常强的代码,而外行可能会将其混淆为语法技能较差的人所写的英语,但它是可以理解的。但该代码需要超过 300 毫秒才能运行。这可能不会造成太大的延迟,但在编程领域,这是一个严重的问题。

另一方面,可以用不同的习惯用法编写相同的代码,运行所需时间少于 10 毫秒。但是,即使是专业的 Python 开发人员也很难理解它。

因此,对于开发人员来说,在这两个极端之间取得平衡是非常重要的。这些类型的代码在业界被称为惯用代码。

根据定义,惯用代码是一种用您的语言的 通用方式 执行 通用任务 的代码。换句话说,惯用代码是任何易于阅读,同时又非常高效的代码。

我在 twitter 上经常关注 Raymond Hettinger (@raymondh),他是 Python 社区的核心开发人员之一,他为 Python 存储库贡献了大量代码,使 Python 语言更加习惯化。

在本博客中,我将介绍一些帮助您改进 Python 代码的技术。开始:

range()

让我们从最明显的开始,假设你需要从 2 迭代到 10。所以如果你是一个绝对的初学者,你可能会写这样的东西:

for i in [2,3,4,5,6,7,8,9,10]:
    print(i)

这样的方法是可行的,也是可以理解的,它不是一个 可扩展 的方法。如果你想循环 2200万 呢。

在这种情况下,可以使用 range(stop)range(start, stop, [step,]) 内置函数。

range 函数自动为您生成列表。例如,你可以将上面的代码改写为:

for i in range(2, 11):
    print(i)

注意我是怎么写的,从 2 开始到 11 结束,而不是 10。这是因为 range 函数循环到 stop - 1。在距离函数中除了开始和停止还有一个参数,那就是步长。步长决定范围必须跳过多少个数字。

假设您需要打印从 210 的所有偶数,在这种情况下,skip 参数将为 2 。缺省值是 1

for i in range(2,11,2):
    print(i)

# OUTPUT: 2 4 6 8 10

现在假设您需要遍历一个列表。有了 range() 的知识,你可以这样做:

cloths = ['shirt', 'hat', 'socks', 'shorts']

for i in range(len(cloths))
    print(cloths[i])

但在 Python 中,有更好的方法:

cloths = ['shirt', 'hat', 'socks', 'shorts']

for cloth in cloths
  print(cloth)

zip()

假设你有两个不同尺寸的列表,颜色和布料,你想要配对它们,直到较小的列表结束。在这种情况下,你可以写这样的代码:

colours = ['pink', 'red', 'green']
cloths = ['shirt', 'hat', 'socks', 'shorts']

n = min(len(colours), len(cloths))
for i in range(n):
    print(colours[i], cloths[i])

# OUTPUT
# pink shirt
# red hat
# green socks

这很好,但你也可以使用内置函数 zip(*iterables)。这个函数最好的一点是,你可以传递 任意数量 的列表,而不仅仅是两个。让我重写上面的代码,然后向您解释 zip 是如何工作的。

colours = ['pink', 'red', 'green']
cloths = ['shirt', 'hat', 'socks', 'shorts']

for colour, cloth in zip(colours, cloths):
    print(colour, cloth)

# OUTPUT
# pink shirt
# red hat
# green socks

您可能已经猜到,zip 接受任意数量的列表并返回包含每个列表中的一个元素的另一个列表。如您所见,两个版本产生相同的输出,但第二个版本看起来更干净。

reversed()

如果你想反向循环一个列表,传统的方法是这样的。

cloths = ['shirt', 'hat', 'socks', 'shorts']

for i in range(len(cloths)-1, -1, -1):
    print(cloths[i])
    
# Output
# -------
# shorts
# socks
# hat
# shirt

但是在 Python 中,您可以使用名为 reversed() 的内置函数。看看这个例子:

cloths = ['shirt', 'hat', 'socks', 'shorts']

for cloth in reversed(cloths):
    print(cloth)
    
# Output
# -------
# shorts
# socks
# hat
# shirt

第二个比第一个更干净更快。

enumerate()

您希望循环通过一个列表和索引。这在传统编程中非常直接:

cloths = ['shirt', 'hat', 'socks', 'shorts']

for i in range(len(cloths)):
    print(i, cloths[i])

# Output
# -------
# 0 shorts
# 1 socks
# 2 hat
# 3 shirt

但在 Python 中有一种更干净、更有效的方法:

cloths = ['shirt', 'hat', 'socks', 'shorts']

for i, cloth in enumerate(cloths):
    print(i, cloth)

# OUTPUT
# -------
# 0 shorts
# 1 socks
# 2 hat
# 3 shirt

sorted()

您需要 按排序顺序 遍历列表,而不是运行排序算法,您可以使用 sorted() 内置方法。

nums = [2,3,1,5,2]

for i in sorted(nums):
    print(i)

# OUTPUT
# ------
# 1
# 2
# 2
# 3
# 5

Python 排序函数使用 Tim Sort,其平均复杂度为 n*log(n)

对于 反向 排序,可以使用 sorted(nums, reverse=True)

你想对字符串列表排序,它会默认根据 字母 排序。

cloths = ['shirt', 'hat', 'socks', 'shorts']

for cloth in sorted(cloths):
    print(cloth)

# OUTPUT
# ------
# hat
# shirt
# shorts
# socks

但如果你想根据字符串的 长度 排序,你可以用 key 属性。例如:

cloths = ['shirt', 'hat', 'socks', 'shorts']

for cloth in sorted(cloths, key=len):
    print(cloth)

# OUTPUT
# ------
# hat
# shirt
# socks
# shorts

以上就是 5 种可以让你的 Python 代码更习惯的技巧。