原文作者:我辈李想
版权声明:文章原创,转载时请务必加上原文超链接、作者信息和本声明。
文章目录
- 一、推导式
- 1.列表推导式
- 2.集合推导式
- 3.字典推导式
- 二、迭代器
- 三、生成器
- 1.yield 生成器
- 2.元组生成器
- 3.生成器中重要方法
- 四、装饰器
- 1.函数装饰器
- 2.可传参函数装饰器
- 3.类装饰器
- 4.可传参的类装饰器
一、推导式
语法格式为:
new_set = {expression for item in iterable if condition}
其中,
new_set 是新生成的集合;
expression 是一个表达式,用于计算集合中元素的值;
item 是集合的元素;
iterable 是一个可迭代对象,如列表、元组、字符串等;
if 语句是可选的,用于筛选元素。
1.列表推导式
列表推导式是 Python 中常用的一种快速创建列表的方式。它可以通过一行代码来生成一个新的列表,而不需要繁琐的循环和条件语句。
下面是一个简单的示例,演示了如何使用列表推导式生成一个1到10的平方数列表:
squares = [x**2 for x in range(1, 11)]
print(type(squares))
print(squares)
输出结果
<class 'list'>
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
列表推导式也可以使用条件语句来过滤元素。下面是一个示例,演示了如何使用列表推导式生成1到10的平方数列表,但只包括偶数:
squares = [x**2 for x in range(1, 11) if x % 2 == 0]
print(type(squares))
print(squares)
输出结果
<class 'list'>
[4, 16, 36, 64, 100]
在上面的示例中,列表推导式使用for循环语句遍历1到10的整数,但只包括偶数,并使用x**2计算每个偶数的平方,然后将结果添加到新的列表中。
列表推导式的优点是可读性高,能够快速创建列表。但是,当可读性受到影响或数据处理较复杂时,建议使用传统的循环和条件语句
2.集合推导式
Python 集合推导式是用来生成集合的一种快捷方式,它类似于列表推导式。
new_set = {x**2 for x in range(1,6)}
print(type(new_set))
print(new_set)
输出结果
<class 'set'>
{1, 4, 9, 16, 25}
上面的例子是生成由 1 到 5 的平方组成的集合。
3.字典推导式
字典推导式的语法与列表推导式和集合推导式类似,但是需要使用花括号 {},可以加入条件表达式等来筛选元素,实现更加复杂的生成。
my_dict = {i: i ** 2 for i in range(1, 6)}
print(type(my_dict))
print(my_dict)
输出结果
<class 'dict'>
{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
在上面的例子中,我们使用了一个字典生成器,将 1 到 5 的整数作为字典的键,并将其平方作为值。
二、迭代器
在Python中,迭代器(Iterator)和可迭代对象(Iterable)是两个重要的概念。
可迭代对象是指实现了 iter 或者 getitem 方法的对象,例如列表、元组、集合、字典、字符串等。这些对象可以通过 for 循环进行迭代,或者使用 iter() 函数将其转换为迭代器。
迭代器是指实现了 iter 和 next 方法的对象。__iter__方法返回迭代器对象本身,__next__方法返回数据集合中的下一个元素,如果没有下一个值,就抛出 StopIteration 异常。迭代器只能向前遍历一次,无法回到前面的位置。
示例:迭代对象转迭代器
my_list = [1, 2, 3]
iterator = iter(my_list)
print('my_list',type(my_list))
print('iterator',type(iterator))
输出结果
my_list <class 'list'>
iterator <class 'list_iterator'>
需要注意的是,虽然可迭代对象可以使用 iter() 函数转换为迭代器,但是迭代器本身也是可迭代对象。也就是说,迭代器可以在 for 循环中直接使用。
my_list = [1, 2, 3]
iterator = iter(my_list)
for item in iterator:
print(item)
迭代器是一个可以遍历数据集合的对象,它的作用是提供一种统一的访问数据集合的方法,而不必关注数据的底层实现方式。
示例:创建一个迭代器
class MyIterator:
def __iter__(self):
self.a = 1
return self
def __next__(self):
x = self.a
self.a += 1
return x
my_iter = MyIterator()
my_iter_iter = iter(my_iter)
print(type(my_iter_iter))
print(next(my_iter_iter))
print(next(my_iter_iter))
print(next(my_iter_iter))
输出
<class '__main__.MyIterator'>
1
2
3
三、生成器
生成器是一种特殊的迭代器,它可以动态地生成数据而不是从一个固定的数据集合中返回数据。Python中的生成器是通过yield关键字来实现的。当函数中包含yield时,该函数就成为生成器函数,并返回一个生成器对象。
1.yield 生成器
示例1:
def num_generator(n):
for i in range(1, n+1):
yield i
# 使用生成器函数生成1到10的数字序列
print(type(num_generator(10)))
for num in num_generator(10):
print(num)
输出
<class 'generator'>
1
2
3
4
5
6
7
8
9
10
其中,生成器函数num_generator()使用yield语句生成数字序列,并在每次调用时返回一个值。使用for循环迭代生成器对象,每次迭代从生成器函数中获取一个值并打印。
2.元组生成器
示例2:
tuple_generator = (i for i in range(10))
result_tuple = tuple(tuple_generator)
print(type(tuple_generator))
print(type(result_tuple))
print(result_tuple)
输出结果
<class 'generator'>
<class 'tuple'>
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
在这个例子中,我们使用了生成器表达式 (i for i in range(10)) 来生成一个可迭代对象,然后使用 tuple() 函数将其转换为元组。
3.生成器中重要方法
next、send、throw是生成器中的3个重要方法,其中next和send可用于遍历生成器,throw用于抛出异常。
其中next函数使用时,当已经遍历到生成器的结尾,会抛一个异常StopIteration
其中send函数使用时,生成器的第一个值必须使用send(None)
其中throw效果等同于raise
生成器的优点是节省内存,因为它不会一次性生成所有值,而是逐个生成并在使用后释放内存。另外,生成器可以通过迭代器协议与其他Python对象进行交互,包括列表、字典等等。
四、装饰器
1.函数装饰器
Python装饰器是一种高级语法,它可以在不修改原函数代码的情况下,增加或改变原函数的功能。装饰器本质上是一个函数,它可以接收一个函数作为参数,并返回一个新的函数。
@decorator
def function():
pass
其中 decorator 是一个装饰器函数,用于增强 function 函数的功能。装饰器函数的定义如下:
def decorator(func):
def wrapper(*args, **kwargs):
# 在这里增加或改变 func 函数的功能
print(f'calling {func.__name__}()')
return func(*args, **kwargs)
return wrapper
装饰器函数 decorator 接收一个函数 func,并返回一个新的函数 wrapper。wrapper 函数可以在调用原函数之前或之后执行一些操作,然后调用原函数并返回其结果。
计时器示例:
import datetime
def timer(func):
def wrapper(*args, **kwargs):
start_time = datetime.datetime.now()
result = func(*args, **kwargs)
end_time = datetime.datetime.now()
print('{0} run time is {1}'.format(func.__name__, (end_time - start_time).total_seconds()))
return result
return wrapper
@timer
def my_function():
time.sleep(2)
print("Function complete.")
my_function()
其中 timer函数是装饰器函数,它接受一个函数作为参数,返回一个新函数wrapper。wrapper函数用于记录被装饰函数执行的时间,并在执行完毕后输出时间。最后,将my_function函数使用@timer装饰器修饰,从而实现函数计时的功能。
2.可传参函数装饰器
装饰器函数也是函数,既然是函数,那么就可以进行参数传递,咱们怎么写一个带参数的装饰器呢
import datetime
def time_msg(msg=None):
def timer(func):
def wrapper(*args, **kwargs):
start_time = datetime.datetime.now()
result = func(*args, **kwargs)
end_time = datetime.datetime.now()
print('{0}:{1} run time is {2}'.format(msg,func.__name__, (end_time - start_time).total_seconds()))
return result
return wrapper
return timer
@time_msg(msg="baiyu")
def my_function():
time.sleep(2)
print("Function complete.")
my_function()
3.类装饰器
在python中,可以用类来实现装饰器的功能,称之为类装饰器。类装饰器的实现是调用了类里面的__call__函数。类装饰器的写法比我们装饰器函数的写法更加简单。
import datetime
class MyDecorator:
def __init__(self, func):
self.func = func
print("执行类的__init__方法")
def __call__(self, *args, **kwargs):
print('进入__call__函数')
start_time = datetime.datetime.now()
result = self.func(*args, **kwargs)
end_time = datetime.datetime.now()
print('{0}:{1} run time is {2}'.format('',self.func.__name__, (end_time - start_time).total_seconds()))
result.atrr = '自定义附加参数' # 类调用时可
return result
@MyDecorator
def my_function():
time.sleep(2)
print("Function complete.")
@MyDecorator
class MyClass:
print("MyClass.")
# my_function()
obj = MyClass()
print(obj.attr) # '附加参数'
4.可传参的类装饰器
import datetime
class MyDecorator(object):
def __init__(self, arg1, arg2):
self.arg1 = arg1
self.arg2 = arg2
def __call__(self,func):
print('进入__call__函数')
def wrapped(*args, **kwargs):
print("Decorator arguments:", self.arg1, self.arg2)
start_time = datetime.datetime.now()
result = func(*args, **kwargs)
end_time = datetime.datetime.now()
print('{0}:{1} run time is {2}'.format('',func.__name__, (end_time - start_time).total_seconds()))
result.attr = '自定义附加参数' # 类调用时可用
return result
return wrapped
@MyDecorator('参1','参2')
class MyClass:
print("MyClass.")
obj = MyClass()
print(obj.attr) # '附加参数'