我们经常有这样的经历:花了很长时间编写和调试一个特定功能的函数,却发现Python已经有类似的内置函数。我们常常在重复造轮子。Python包含了许多强大的内置函数,使用这些函数来简化代码可以为我们节省宝贵的时间。
接下来,我们将介绍一些我们经常忽略的强大Python内置函数。
ZIP_Longest
合并不同大小的可迭代对象。Python中的zip_longest()函数来自itertools模块,允许你将多个长度不同的可迭代对象进行合并。与zip()不同,后者会在最短的可迭代对象处停止,zip_longest()会一直合并,直到最长的可迭代对象耗尽,缺失的值会用指定的fillvalue填充(默认为None)。
- 处理不等长的可迭代对象:在处理长度不同的可迭代对象时非常有用,确保由于尺寸不均而没有数据丢失。
- 允许自定义填充:fillvalue参数允许你指定如何处理缺失值,这为合并来自多个来源的数据提供了灵活性。
zip_longest()函数可以用于:
- 合并来自多个来源的数据,尤其是长度不均匀的数据。
- 比较没有直接关联的数据点。
- 处理不等维度的矩阵或网格。
from itertools import zip_longest
list1 = [1, 2, 3]
list2 = ['a', 'b']
list3 = ['X', 'Y', 'Z', 'W']
result = list(zip_longest(list1, list2, list3))
print(result)
result = list(zip_longest(list1, list2, list3, fillvalue='-'))
print(result)
图片
Divmod
divmod(a, b)函数返回一个包含商和余数的元组,当将a除以b时。它是a // b(商)和a % b(余数)的组合形式。
这个函数在需要同时得到商和余数的情况下非常实用。它通过一步操作代替了两个独立的操作(整数除法和取模),从而减少了开销。
divmod()在以下场景中非常有用:
- 当你需要将秒转换为分钟和秒,小时转换为分钟和小时等时,divmod()可以快速计算这两个值。
- 计算货币分解,例如将总金额分解为较大的面额和较小的零钱。
a = 20
b = 6
result = divmod(a, b)
print(result)
quotient, remainder = result
print(f"Quotient: {quotient}, Remainder: {remainder}")
图片
Compile
将代码编译为字节码,快速而简洁。Python中的compile()函数将源代码编译为可以稍后执行的代码对象。它允许你将一段Python代码字符串转换为代码对象,然后可以将其传递给exec()或eval()进行执行。
图片
compile()函数允许你动态执行存储在字符串中的Python代码,这在一些高级用例中非常有用,例如模板引擎、REPL系统或动态生成代码时。
code_string = '3 * 4 + 5'
compiled_code = compile(code_string, '<string>', 'eval')
print(compiled_code)
result = eval(compiled_code)
print(result)
图片
Bytearray
创建和修改字节序列。bytearray()函数创建一个可变的字节序列,它是字节数据的灵活表示形式。与不可变的bytes不同,bytearray允许修改,适用于需要操作或更新字节数据的场景。
图片
bytearray允许修改,适用于需要动态构建或更改字节数据的场景。在处理文件、网络协议或流中的二进制数据时,它非常有用,尤其是在需要频繁修改的情况下。
data = bytearray("Hello, World!", "utf-8")
print(data)
data[7:12] = b'Python'
print(data)
图片
Repr
查看对象背后的代码。Python中的repr()函数返回对象的字符串表示形式,理想情况下可以使用eval()函数重新创建该对象。它提供对象的正式字符串表示,适用于调试和日志记录。
图片
number = 42
string = "Hello, World!"
list_obj = [1, 2, 3]
print(repr(number))
print(repr(string))
print(repr(list_obj))
图片
Memoryview
轻松实现直接内存访问。Python中的memoryview()函数创建一个内存视图对象,允许你访问支持缓冲区协议的对象的内部数据,而无需复制数据。这在高效处理大数据集时特别有用,因为它允许对数据的切片进行操作。
图片
memoryview()通过允许直接访问对象的底层内存,避免了复制数据的开销。在科学计算或数据分析中,处理大型数组或缓冲区非常常见,memoryview()可以通过减少内存使用大大提升性能。
data = bytearray(b"Hello, World!")
mv = memoryview(data)
print(mv[0:5].tobytes())
图片
Property
集成getter、setter和deleter于一体。property()函数是一个内置函数,它创建并返回一个属性对象,这是一种特殊的属性类型,允许对对象属性进行管理式访问。属性支持为属性定义getter、setter和deleter方法,促进了封装和数据隐藏。
图片
- 封装:允许控制属性的访问和修改方式,支持验证和日志记录。
- 惰性计算:支持属性的惰性计算,只有在访问时才计算其值。
当你希望对属性的修改施加规则时,property()非常有用。
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
"""The radius property."""
return self._radius
@radius.setter
def radius(self, value):
if value < 0:
raise ValueError("Radius cannot be negative")
self._radius = value
@property
def area(self):
"""The area property."""
return 3.14159 * (self._radius ** 2)
circle = Circle(5)
print(circle.radius)
circle.radius = 10
print(circle.area)
try:
circle.radius = -5
except ValueError as e:
print(e)
图片
Frozensets
用于高效操作的不可变集合。frozenset()函数返回一个不可变的集合对象,意味着一旦创建,其元素无法被更改(添加或删除)。这允许创建可用于字典键或存储在其他集合中的集合。
以下是一些使用此函数的场景:
- 当你需要一个在其生命周期内不应更改的集合时。
- 作为字典中的键,以确保项目的唯一性。
- 由于frozenset是不可变的,它们可以用作字典的键。
my_frozenset = frozenset([1, 2, 3, 4, 5])
print(my_frozenset)
my_frozenset.add(6)
图片
Callable
callable()是Python中的一个内置函数,用于检查一个对象是否可调用。callable()通过在调用之前验证对象是否可调用,防止运行时错误。当处理可能在运行时被调用的对象时,特别是在复杂的应用中,函数、lambda表达式或对象可能会被传递和互换使用,callable()非常有用。
这个内置函数适用于以下情况——当函数、lambda表达式或对象可能互换使用时,callable()可以帮助验证它们是否可以被调用。
图片
还可以通过定义__call__()方法,使自定义类的实例变得可调用。
class Dog:
def __call__(self, sound):
return f"The dog says {sound}"
dog = Dog()
print(callable(dog))
print(dog("woof"))
图片
在这里,Dog类通过实现__call__()方法变得可调用。dog实例表现得像一个函数,允许你直接向其传递参数。
dis
Python中的dis模块提供了用于反汇编Python字节码的函数,这对于理解Python如何执行代码以及调试非常有用。这个模块使开发者能够查看Python执行的低级操作。它还可以通过检查字节码来帮助识别性能瓶颈。
import dis
def fibonacci(n):
if n <= 1:
return n
else:
return fibonacci(n-1) + fibonacci(n-2)
dis.dis(fibonacci)
将输出fibonacci的字节码指令,显示Python执行该函数时所执行的操作。
图片
Python的内置函数显著提升了开发效率。常用函数包括:
- zip_longest():合并不等长的可迭代对象,避免数据丢失。
- divmod():同时获取商和余数,简化计算。
- compile():动态执行代码。
- bytearray():处理可变字节序列,适合频繁修改的场景。
- memoryview():提供高效的内存访问。
- property():支持数据封装与访问控制。
- frozenset():创建不可变集合,适用于字典键。
- callable():检查对象是否可调用。
- dis模块:帮助理解字节码,识别性能瓶颈。
合理利用这些函数可以提升代码的简洁性和可读性。