if-else 三元运算符
a = 5
b = 10
max = a if a > b else b # value_if_true if condition else value_if_false
print(max)
# 10
# 检查“a”是否大于“b”,如果为真则返回“a”,如果为假则返回“b”
enumerate() 枚举函数
# enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标
enumerate(sequence, start=0)
# sequence - 一个序列、迭代器或其他支持迭代对象。
# start - 下标起始位置。
question = ['Why', 'are', 'you', 'learning', 'Python']
for i, v in enumerate(question):
print(i, v)
# 输出:
0 Why
1 are
2 you
3 learning
4 Python
#我们也可以从指定的 start 参数开始计数:
for i, v in enumerate(question, start = 1):
print(i, v)
# 输出
1 Why
2 are
3 you
4 learning
5 Python
zip() 压缩函数
# zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
zip(iter1, iter2, iter3, ...)
list1 = [1, 2, 3]
list2 = [4, 5, 6]
zipped = zip(list1, list2)
print(zipped) # <zip object at 0x7fd360e0bb70> 打印迭代器的内存地址
print(list(zipped))
# [(1, 4), (2, 5), (3, 6)]
# 转换为列表后,打印所有的元组
for i in zipped:
print(i)
# (1, 4)
# (2, 5)
# (3, 6)
# 遍历迭代器打印每个元组
列表推导式(list comprehension)
[expression for item in iterable]
- expression 是每个元素x的平方,也就是x**2
- item 是x
- iterable 是 range(1,6),从1到5
squared_numbers = [x**2 for x in range(1, 6)]
# 对于range(1,6)返回的每个元素x,计算它的平方(x**2),最后形成一个新列表。
# 等价于
squared_numbers = []
for x in range(1, 6):
squared_numbers.append(x ** 2)
print(squared_numbers)
# [1, 4, 9, 16, 25]
匿名函数lambda
lambda 参数:表达式
# 整数平方
square = lambda x: x * x
print(square(3)) # 9
#匿名函数通常用于需要简短函数的场景,例如作为参数传递
nums = [1, 2, 3, 4]
print(list(map(lambda x: x * x, nums)))
# [1, 4, 9, 16]
迭代模块itertools
Python的迭代模块itertools提供了一组用于快速、高效迭代和组合迭代器的工具函数
# itertools.count(start=0, step=1): 这个函数返回一个无限迭代器,从start开始,每次增加step。例如:
import itertools
for i in itertools.count(1, 2):
if i > 10:
break
print(i)
#这将打印从1开始的奇数,直到大于10为止。
#itertools.cycle(iterable): 这个函数返回一个无限迭代器,从iterable中的第一个元素开始,然后重复迭代。例如:
import itertools
colors = itertools.cycle(['red', 'green', 'blue'])
for i in range(5):
print(next(colors))
#这将打印`'red', 'green', 'blue', 'red', 'green'`。
# itertools.chain(*iterables): 这个函数将多个迭代器连接成一个迭代器。例如:
import itertools
numbers = [1, 2, 3]
letters = ['a', 'b', 'c']
for item in itertools.chain(numbers, letters):
print(item)
#这将打印`1, 2, 3, 'a', 'b', 'c'`。
# `itertools.product(*iterables, repeat=1)`: 这个函数返回一个迭代器,为每个迭代器中的元素生成所有可能的组合。例如:
import itertools
colors = ['red', 'green', 'blue']
sizes = ['small', 'medium', 'large']
for item in itertools.product(colors, sizes):
print(item)
# 这将打印所有可能的颜色和尺寸组合,例如`('red', 'small'), ('red', 'medium'), ('red', 'large')`等。
这只是itertools
模块中一些常用的函数示例,它还提供了许多其他有用的函数来操作迭代器。可以使用dir(itertools)
命令来列出所有可用的函数,并使用help(function_name)
命令来查看有关特定函数的详细信息。
生成器(Generator)
生成器(Generator)是Python中一种特殊的迭代器,可以使用函数来创建。与函数返回单个值不同,生成器可以生成多个值,并且在生成器函数中可以使用yield
关键字来产生值。生成器函数每次产生一个值后会挂起并保存当前状态,等待下一次调用时从上一次挂起的地方继续执行。
以下是一个简单的生成器函数示例:
def my_generator():
yield 1
yield 2
yield 3
在生成器函数中,使用yield
关键字来产生值。在调用生成器函数时,它将返回一个生成器对象,该对象可以用于迭代生成器函数中产生的值。例如:
gen = my_generator()
print(next(gen)) # 输出 1
print(next(gen)) # 输出 2
print(next(gen)) # 输出 3
在上面的示例中,我们首先创建了一个my_generator
生成器函数,该函数会产生1、2和3这三个值。然后,我们通过调用my_generator
函数创建了一个生成器对象gen
,并使用next
函数来逐个获取生成器中产生的值。每次调用next
函数时,生成器函数会从上一次挂起的地方继续执行,产生下一个值,直到所有的值都被产生完毕,此时再次调用next
函数将会抛出StopIteration
异常。
除了使用next
函数来迭代生成器外,还可以使用for
循环来遍历生成器产生的值。例如:
gen = my_generator()
for value in gen:
print(value)
这将依次输出1、2和3这三个值。
生成器的一个重要特点是它能够按需生成值,即在需要的时候才进行计算,而不是一次性生成所有的值。这使得生成器适用于处理大量数据或需要耗费大量时间计算的数据集合,可以节省内存和计算资源。
除了使用生成器函数来创建生成器外,Python还提供了一些用于创建生成器的语法糖,例如生成器表达式和yield from
语句。生成器表达式类似于列表推导式,但返回的是一个生成器对象。以下是一个生成器表达式的示例:
gen = (x**2 for x in range(5))
for value in gen:
print(value)
这将输出0、1、4、9和16这五个值,它们是0到4的平方。
yield from
语句可以用于在生成器中调用另一个生成器,将其生成的所有值透明地传递给外部生成器。以下是一个yield from
语句的示例:
def my_subgenerator():
yield 'a'
yield 'b'
yield 'c'
def my_generator():
yield from my_subgenerator()
yield 1
yield 2
yield 3
gen = my_generator()
for value in gen:
print(value)
在上面的示例中,我们首先定义了一个my_subgenerator
生成器函数,它会产生三个值’a’、‘b’和’c’。然后,我们在my_generator
生成器函数中使用yield from
语句来调用my_subgenerator
函数,并将其生成的所有值透明地传递给外部生成器。在my_generator
函数中,我们还产生了三个值1、2和3。最后,我们通过遍历my_generator
生成器对象来输出所有的值。输出结果为:
a
b
c
1
2
3
可以看到,my_subgenerator
函数产生的三个值被透明地传递给了外部生成器my_generator
,并与后面的三个值一起输出。yield from
语句的使用可以简化生成器中的嵌套,并使得生成器的逻辑更加清晰和易于理解。
作用与应用
当然可以,请参考以下具体的代码实现案例:
- 处理大量数据:
# 使用生成器处理大量数据
def read_large_file(file_path):
with open(file_path, 'r') as f:
while True:
data = f.readline()
if not data:
break
yield data
# 使用生成器按需处理数据
for line in read_large_file('large_file.txt'):
# 处理每一行数据
process_data(line)
在上面的代码中,我们定义了一个read_large_file
生成器函数,它可以逐行读取大文件中的数据,并按需生成数据。然后,我们使用for
循环遍历生成器对象,按需处理每一行数据。这种方式可以避免将整个文件读入内存中,从而节省内存和计算资源。
- 惰性计算:
# 使用生成器惰性计算数据
def fibonacci():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
# 输出斐波那契数列前10个数
gen = fibonacci()
for i in range(10):
print(next(gen))
在上面的代码中,我们定义了一个fibonacci
生成器函数,它可以生成无限的斐波那契数列。然后,我们使用next
函数逐个获取生成器中产生的值,直到输出前10个斐波那契数。
- 管道和过滤器:
# 使用生成器实现管道和过滤器模式
def filter_words(words, func):
for word in words:
if func(word):
yield word
words = ['apple', 'banana', 'cherry', 'durian', 'elderberry']
filtered_words = filter_words(words, lambda x: len(x) > 5)
for word in filtered_words:
print(word)
在上面的代码中,我们定义了一个filter_words
生成器函数,它可以接受一个词汇列表和一个过滤函数作为参数,按需生成符合过滤条件的单词。然后,我们使用lambda
表达式定义一个过滤函数,该函数返回单词长度大于5的单词。最后,我们使用for
循环遍历生成器对象,输出符合条件的单词。
- 数据流处理:
# 使用生成器实现数据流处理
def read_data_from_network():
# 从网络读取数据
while True:
data = read_data()
if not data:
break
yield data
def process_data(data):
# 处理数据
processed_data = process(data)
return processed_data
def write_data_to_file(processed_data):
# 将处理后的数据写入文件
write_data(processed_data)
# 将数据流从网络读取,经过处理后写入文件
for data in read_data_from_network():
processed_data = process_data(data)
write_data_to_file(processed_data)
在上面的代码中,我们定义了三个生成器函数,分别用于从网络读取数据、处理数据和将处理后的数据写入文件。然后,我们使用for
循环遍历从网络读取的数据流,将每个数据块经过处理后写入文件。这种方式可以实现数据流的实时处理和持续输出。
- 协程和异步编程:
# 使用生成器实现协程和异步编程
def coroutine():
while True:
data = yield
# 处理数据
processed_data = process(data)
# 发送处理后的数据
send_data_to_server(processed_data)
# 创建协程对象
coro = coroutine()
# 启动协程
next(coro)
# 向协程发送数据
coro.send(data)
在上面的代码中,我们定义了一个coroutine
生成器函数作为协程,它可以接受从外部发送过来的数据,并将处理后的数据发送到服务器。然后,我们创建了一个协程对象coro
,并使用next
函数启动协程。最后,我们使用send
函数向协程对象发送数据,并将处理后的数据发送到服务器。
- 流式API:
# 使用生成器实现流式API
def filter_stream(stream, func):
for data in stream:
if func(data):
yield data
def transform_stream(stream, func):
for data in stream:
yield func(data)
def limit_stream(stream, n):
for i, data in enumerate(stream):
if i >= n:
break
yield data
# 流式处理数据
stream = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
stream = filter_stream(stream, lambda x: x % 2 == 0)
stream = transform_stream(stream, lambda x: x * 2)
stream = limit_stream(stream, 3)
for data in stream:
print(data)
在上面的代码中,我们定义了三个生成器函数,分别用于过滤、转换和限制数据流的大小。然后,我们创建了一个数据流,将其分别经过过滤、转换和限制处理后输出前三个结果。这种方式可以实现类似于流式查询、流式处理等功能,使得代码更加简洁、易于理解和维护。
装饰器(Decorator)
装饰器(Decorator)是Python中一种特殊的函数,它可以用于修改或扩展其他函数的功能。装饰器本身也是一个函数,它接受一个函数作为参数,并返回一个新的函数。通常情况下,装饰器会在不修改原有函数的情况下,为其添加一些额外的功能或修改其行为。
def my_decorator(func):
def wrapper():
print('Before function call')
func()
print('After function call')
return wrapper
@my_decorator
def my_function():
print('Inside function')
my_function()
"""
输出:
Before function call
Inside function
After function call
"""
在上面的代码中,我们首先定义了一个装饰器函数my_decorator
,它接受一个函数作为参数,并返回一个新的函数wrapper
。wrapper
函数在调用原有函数前后会打印一些额外的信息。然后,我们使用@my_decorator
语法糖将装饰器应用到my_function
函数上。最后,我们调用my_function
函数,实际上调用的是经过装饰器处理后的wrapper
函数。
需要注意的是,装饰器可以装饰任意类型的函数,包括普通函数、方法、类方法、静态方法等。在不同的情况下,传入装饰器的函数参数也会有所不同。例如,当装饰类方法时,需要将第一个参数指定为cls
,表示类本身。以下是一个装饰类方法的示例:
def my_decorator(func):
def wrapper(cls, x, y):
print('Before method call')
result = func(cls, x, y)
print('After method call')
return result
return wrapper
class MyClass:
@my_decorator
def my_method(cls, x, y):
return x + y
obj = MyClass()
print(obj.my_method(1, 2))
"""
输出:
Before method call
After method call
3
"""
不定数量的参数
在Python中,可以使用不定数量的参数来传递任意数量的位置参数和关键字参数。这里介绍两种常用的不定数量参数的定义方式:
-
*args参数:用于传递任意数量的位置参数,它会将所有传入的位置参数封装为一个元组(tuple)。例如:
def print_args(*args): for arg in args: print(arg) print_args(1, 2, 3) # 输出:1 2 3
-
**kwargs参数:用于传递任意数量的关键字参数,它会将所有传入的关键字参数封装为一个字典(dict)。例如:
def print_kwargs(**kwargs): for key, value in kwargs.items(): print(f"{key}: {value}") print_kwargs(a=1, b=2, c=3) # 输出:a: 1 b: 2 c: 3
在实际使用中,可以同时使用*args和**kwargs参数,来接收任意数量的位置参数和关键字参数。例如:
def print_args_and_kwargs(*args, **kwargs):
for arg in args:
print(arg)
for key , value in kwargs.items():
print(f"{key}: {value}")
print_args_and_kwargs(1, 2, 3, a=1, b=2, c=3) # 输出:1 2 3 a: 1 b: 2 c: 3
不定数量参数的使用可以使得函数更加灵活和通用,可以适应不同数量和类型的参数传递。在实际开发中,需要根据具体的需求和场景选择合适的参数传递方式和参数数量,以使函数更加简洁、易于理解和使用。
动态导入
动态导入是指在程序运行时根据需要动态地加载模块或者函数,而不是在程序编译时进行静态导入。Python提供了几种动态导入的方法,以下是其中的两种常见方法:
-
importlib模块:importlib模块提供了一系列函数,可以在程序运行时动态地导入模块或者函数。例如:
import importlib module_name = "math" module = importlib.import_module(module_name) print(module.pi) # 输出:3.141592653589793
-
import()函数:Python内置的__import__()函数可以用于在程序运行时动态地导入模块或者函数。例如:
module_name = "math" module = __import__(module_name) print(module.pi) # 输出:3.141592653589793
动态导入的好处在于可以根据需要动态地加载模块或者函数,避免在程序启动时就加载所有模块或者函数,从而提高程序的性能和效率。此外,动态导入还可以使得程序更加灵活和可扩展,可以根据不同的需求和场景动态地加载模块或者函数,使得程序更加灵活和通用。
需要注意的是,在使用动态导入时需要注意安全性和可靠性,避免加载不安全的或者恶意的模块或者函数,从而保障程序的安全和稳定性。
字典生成式
字典生成式是一种快速创建和初始化字典的方式。它类似于列表生成式,但可以用于创建字典。以下是一个简单的字典生成式的例子:
numbers = [1, 2, 3, 4, 5]
squares = {num: num ** 2 for num in numbers}
print(squares) # 输出:{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
上面的代码使用了一个字典生成式,将一个包含5个整数的列表转换成了一个字典,其中字典的键是列表中的每个元素,值是该元素的平方。
字典生成式的语法格式为:{key_expression: value_expression for expression in iterable}
,其中key_expression
和value_expression
分别表示字典键和值的表达式,expression
表示可迭代对象中的每个元素。可以根据需要定义不同的表达式来生成不同的字典。
字典生成式的好处在于可以快速创建和初始化字典,使得代码更加简洁和易于理解。在实际开发中,可以使用字典生成式来处理数据集合,进行数据处理和转换,从而提高程序的效率和可维护性。
可调用对象
在Python中,任何一个对象,只要实现了特定的方法或者属性,就可以被视为可调用对象。可调用对象可以像函数一样被调用,并返回一个结果。以下是几种常见的可调用对象:
-
函数:函数是最常见的可调用对象,它可以接收零个或多个参数,并返回一个结果。例如:
def add(x, y): return x + y result = add(1, 2) print(result) # 输出:3 ```
-
类:类也可以作为可调用对象,在类中实现__call__()方法即可。例如:
class Greeter: def __init__(self, greeting): self.greeting = greeting def __call__(self, name): return f"{self.greeting}, {name}!" greet = Greeter("Hello") result = greet("John") print(result) # 输出:Hello, John
-
lambda函数:lambda函数是一种匿名函数,可以用于定义简单的可调用对象。例如:
add = lambda x, y: x + y result = add(1, 2) print(result) # 输出:3
-
方法:方法是定义在类中的函数,可以通过实例调用。例如:
class Calculator: def add(self, x, y): return x + y calc = Calculator() result = calc.add(1, 2) print(result) # 输出:3
-
实现了__call__()方法的对象:任何实现了__call__()方法的对象都可以作为可调用对象。例如:
class Counter: def __init__(self): self.count = 0 def __call__(self): self.count += 1 return self.count counter = Counter() result1 = counter() # 调用__call__()方法,返回1 result2 = counter() # 调用__call__()方法,返回2 print(result1, result2) # 输出:1 2
可调用对象的概念非常灵活,可以为开发者提供更加灵活的编程方式。在实际开发中,需要根据具体的需求和场景选择合适的可调用对象,从而实现更加高效、灵活和可维护的代码。
用下划线分隔大数字/字符
在Python中,可以使用下划线来分隔长数字或字符串,以使其更易于阅读和理解。这个特性从Python 3.6版本开始引入,可以应用于整数、浮点数和字符串。以下是几个例子:
-
分隔整数:
number = 123_456_789 print(number) # 输出:123456789
-
分隔浮点数:
pi = 3.14_15_92_65_36 print(pi) # 输出:3.1415926536
-
分隔字符串:
message = "Hello, Python!" print(message) # 输出:Hello, Python! message_with_underscore = "Hello,_Python!" print(message_with_underscore) # 输出:Hello,_Python!
使用下划线分隔长数字或字符串可以使得代码更加易于阅读和理解,特别是在处理长数字或字符串时更加有效。但需要注意的是,下划线只是用于分隔,不会影响数字或字符串的值和类型,因此不要在数字或字符串的中间位置使用下划线。
快速合并两个字典
在Python中,有多种方法可以快速合并两个字典。以下是常见的几种方法:
-
使用update()方法:update()方法可以将一个字典的键值对更新到另一个字典中。例如:
dict1 = {"a": 1, "b": 2} dict2 = {"c": 3, "d": 4} dict1.update(dict2) print(dict1) # 输出:{"a": 1, "b": 2, "c": 3, "d": 4} ````
-
使用**操作符:**操作符可以将一个字典解包成关键字参数,可以用于快速合并两个字典。例如:
dict1 = {"a": 1, "b": 2} dict2 = {"c": 3, "d": 4} dict3 = {**dict1, **dict2} print(dict3) # 输出:{"a": 1, "b": 2, "c": 3, "d": 4} ````
-
使用字典推导式:字典推导式可以根据给定的表达式和条件创建一个新的字典对象,也可以用于合并两个字典。例如:
dict1 = {"a": 1, "b": 2} dict2 = {"c": 3, "d": 4} dict3 = {k: v for d in [dict1, dict2] for k, v in d.items()} print(dict3) # 输出:{"a": 1, "b": 2, "c": 3, "d": 4} ````
以上三种方法都可以快速合并两个字典,可以根据具体的需求和场景选择合适的方法。值得注意的是,如果两个字典中有相同的键,后面的字典中的值会覆盖前面的字典中的值。因此,在合并字典时需要注意键的重复问题,以免出现错误结果。
列表、集合和字典是可变的
在Python中,列表(list)、集合(set)和字典(dict)都是可变对象,即它们的值可以在创建后被修改。这意味着可以向它们中添加、删除或修改元素,而不需要创建一个新的对象。以下是它们的一些基本操作:
-
列表(list)的基本操作:
# 创建一个列表 my_list = [1, 2, 3, 4, 5] # 添加一个元素 my_list.append(6) # 删除一个元素 my_list.remove(3) # 修改一个元素 my_list[2] = 10
-
集合(set)的基本操作:
# 创建一个集合 my_set = {1, 2, 3, 4, 5} # 添加一个元素 my_set.add(6) # 删除一个元素 my_set.remove(3) my_set.discard(7) # 如果元素不存在,也不会报错 # 修改一个元素(集合中的元素不可修改)
-
字典(dict)的基本操作:
# 创建一个字典 my_dict = {"a": 1, "b": 2, "c": 3} # 添加一个键值对 my_dict["d"] = 4 # 删除一个键值对 del my_dict["c"] # 修改一个键值对 my_dict["a"] = 10
需要注意的是,由于可变对象可以在创建后被修改,因此在多个变量之间共享可变对象时需要小心。如果多个变量引用同一个可变对象,并且修改了其中一个变量的值,那么其他引用该对象的变量也会受到影响。因此,需要根据具体的需求和场景,合理地使用可变对象,以避免出现不必要的问题。