专业编程基础技术教程

网站首页 > 基础教程 正文

Python中10个最容易被忽略的内建函数

ccvgpt 2024-11-15 16:41:44 基础教程 25 ℃

接上篇,这篇我们讨论下最容易被新手忽略的10个内置函数,这些函数很容易了解,但更容易被 Python 新手忽略,废话不多说,直接开始:


Python中10个最容易被忽略的内建函数

bool

bool 函数检查 Python 对象的True 或False。


对于数字,True是一个非零的数字:

>>> bool(5)
True
>>> bool(-1)
True
>>> bool(0)
False

对于集合,True通常是非空的(集合的长度是否大于 0):

>>> bool('hello')
True
>>> bool('')
False
>>> bool(['a'])
True
>>> bool([])
False
>>> bool({})
False
>>> bool({1: 1, 2: 4, 3: 9})
True
>>> bool(range(5))
True
>>> bool(range(0))
False
>>> bool(None)
False

真条件在 Python 中很重要。


许多 Pythonista 没有询问容器长度的问题,而是询问关于True条件的问题:

# Instead of doing this
if len(numbers) == 0:
    print("The numbers list is empty")


# Many of us do this
if not numbers:
    print("The numbers list is empty")

你可能不会经常看到 bool 被使用,但是当你需要强制一个布尔值来确认它是否为True时,你会想知道 bool。


enumerate

每当需要向上计数,一次一个数字,同时循环遍历一个可迭代对象时,枚举函数就会派上用场。


这似乎是一项非常小众的任务,但它经常出现。


例如,我们可能想要跟踪文件中的行号:

>>> with open('hello.txt', mode='rt') as my_file:
...     for n, line in enumerate(my_file, start=1):
...         print(f"{n:03}", line)
...
001 This is the first line of the file
002 This is the second line
003 This is the last line of the file

enumerate 函数也非常用来跟踪序列中项目的索引。

def palindromic(sequence):
    """Return True if the sequence is the same thing in reverse."""
    for i, item in enumerate(sequence):
        if item != sequence[-(i+1)]:
            return False
    return True

请注意,你可能会看到较新的 Pythonistas 在 Python 中使用 range(len(sequence))。如果曾经看到带有 range(len(...)) 的代码,现在可能你更希望使用 enumerate。

def palindromic(sequence):
    """Return True if the sequence is the same thing in reverse."""
    for i in range(len(sequence)):
        if sequence[i] != sequence[-(i+1)]:
            return False
    return True

zip

zip 函数比 enumerate 更专业。


zip 函数用于同时循环多个迭代。

>>> one_iterable = [2, 1, 3, 4, 7, 11]
>>> another_iterable = ['P', 'y', 't', 'h', 'o', 'n']
>>> for n, letter in zip(one_iterable, another_iterable):
...     print(letter, n)
...
P 2
y 1
t 3
h 4
o 7
n 11

如果必须同时遍历两个列表(或任何其他可迭代对象),则 zip 优于枚举。当在循环时需要索引时, enumerate 函数很方便,但是当我们特别关心一次循环两个可迭代对象时,zip 非常有用。


enumerate 和 zip 都将迭代器返回给我们。迭代器是支持 for 循环的惰性迭代器。


reversed

反转函数,如 enumerate 和 zip,返回一个迭代器。

>>> numbers = [2, 1, 3, 4, 7]
>>> reversed(numbers)
<list_reverseiterator object at 0x7f3d4452f8d0>

我们对这个迭代器唯一能做的就是循环它(仅有一次):

>>> reversed_numbers = reversed(numbers)
>>> list(reversed_numbers)
[7, 4, 3, 1, 2]
>>> list(reversed_numbers)
[]

像 enumerate 和 zip 一样,reverse 是一种循环辅助函数。你会看到 reversed 专门用于 for 循环的 for 部分:

>>> for n in reversed(numbers):
...     print(n)
...
7
4
3
1
2

除了 reversed 函数之外,还有一些其他方法可以反转 Python 列表:

# Slicing syntax
for n in numbers[::-1]:
    print(n)


# In-place reverse method
numbers.reverse()
for n in numbers:
    print(n)

但是 reversed 函数通常是在 Python 中反转任何可迭代对象的最佳方法。


与列表反向方法(例如 numbers.reverse())不同,reversed 不会改变列表(它返回反向项的迭代器)。


与 numbers[::-1] 切片语法不同, reversed(numbers) 不会构建一个全新的列表:它返回的惰性迭代器在我们循环时反向检索下一项。而且 reversed(numbers) 比 numbers[::-1] 更具可读性。


如果我们结合 reversed 和 zip 函数的非复制性质,我们可以重写palindromic函数(来自上面的枚举)而不占用任何额外的内存(这里没有复制列表):

def palindromic(sequence):
    """Return True if the sequence is the same thing in reverse."""
    for n, m in zip(sequence, reversed(sequence)):
        if n != m:
            return False
    return True

sum

sum 函数接受一个可迭代的数字并返回这些数字的总和。

>>> sum([2, 1, 3, 4, 7])
17

这就是它的用法了,没有了。


Python 有很多帮助函数为你做循环,部分原因是它们与生成器表达式很好地配对:

>>> numbers = [2, 1, 3, 4, 7, 11, 18]
>>> sum(n**2 for n in numbers)
524


min and max

min 和 max 函数可以满足你的期望:它们为你提供可迭代项中的最小和最大项。

>>> numbers = [2, 1, 3, 4, 7, 11, 18]
>>> min(numbers)
1
>>> max(numbers)
18

min 和 max 函数使用 < 运算符比较给定的项目。所以所有的值都需要是可排序的并且可以相互比较(幸运的是很多对象在 Python 中都是可排序的)。


min 和 max 函数还接受一个关键函数,以允许自定义“最小”和“最大”对特定对象的真正含义。


sorted

sorted 函数接受任何可迭代对象,并按排序顺序返回该可迭代对象中所有值的新列表。

>>> numbers = [1, 8, 2, 13, 5, 3, 1]
>>> words = ["python", "is", "lovely"]
>>> sorted(words)
['is', 'lovely', 'python']
>>> sorted(numbers, reverse=True)
[13, 8, 5, 3, 2, 1, 1]

sorted 函数,如 min 和 max,使用 < 运算符比较给它的项目,因此给它的所有值都需要是可排序的。


sorted 函数还允许通过键函数(就像 min 和 max)自定义其排序。


any and all

any 和 all 函数可以与生成器表达式配对,以确定可迭代项中的任何或所有项是否与给定条件匹配。


我们之前的palindromic函数检查是否所有项目都等于它们在反向序列中的对应项目(第一个值等于最后一个值,第二个值等于倒数第二个值,等等)。

我们重写palindromic 用all。

def palindromic(sequence):
    """Return True if the sequence is the same thing in reverse."""
    return all(
        n == m
        for n, m in zip(sequence, reversed(sequence))
    )

否定条件和 all 的返回值将允许我们等效地使用 any:

def palindromic(sequence):
    """Return True if the sequence is the same thing in reverse."""
    return not any(
        n != m
        for n, m in zip(sequence, reversed(sequence))
    )

最近发表
标签列表