匿名函数
在Python中,匿名函数通常被称为lambda函数,它是一种可以在定义的地方立即使用的小型、无需命名的函数。
lambda函数的基本语法是:
lambda 参数列表: 返回值
一个简单的示例:
add = lambda x, y: x + y
result = add(3, 5) # 这里调用add函数,result的值将会是8
lambda函数的特点包括:
- 无需显式命名:与传统的函数不同,lambda函数不需要一个明确的名字,因此通常用于一次性或临时的任务。
- 立即执行:lambda函数可以在定义的地方直接调用,不需要像传统函数一样事先定义再调用。
- 适用于简单操作:lambda函数通常用于执行简单的操作,因为它们的语法相对紧凑,不适用于复杂的逻辑。
- 通常用于作为参数传递:lambda函数常用于函数式编程中,可以作为高阶函数的参数传递,例如在
map
、filter
等函数中使用。
下面是一个使用lambda函数作为参数的例子:
numbers = [1, 2, 3, 4, 5]
squared_numbers = list(map(lambda x: x**2, numbers))
# 使用lambda函数计算每个数字的平方,并将结果存储在squared_numbers列表中
常见内置函数
1. map
map
是Python内建的一个高阶函数,它接受一个函数和一个可迭代对象(如列表、元组等),然后将该函数应用于可迭代对象的每个元素,最终返回一个新的可迭代对象,其中包含了所有经过该函数处理后的元素。
map的基本语法如下:
map(function, iterable)
- function 是一个接受一个参数的函数,它将被应用于 iterable 中的每个元素。
- iterable 是一个可以迭代的对象,如列表、元组等。
一个简单示例:
numbers = [1, 2, 3, 4, 5]
squared_numbers = map(lambda x: x**2, numbers)
# squared_numbers 是一个迭代器,包含了每个元素的平方
在这个例子中,map 将 lambda 函数应用于 numbers 列表中的每个元素,得到一个包含平方数的迭代器。
需要注意的是:
- map 返回一个迭代器,因此如果需要将结果转换为列表,需要使用 list 函数将其转换。
- map 中的函数可以是任何可以接受一个参数的函数,不仅仅是匿名函数。
- 使用map函数速度快于for循环
map 函数非常适合用于对列表或其他可迭代对象中的每个元素进行相似的操作,从而避免了编写显式的循环。
2. zip
zip
是Python的一个内建函数,它允许你将多个可迭代对象(如列表、元组等)打包成一个元组的序列。这可以用于同时遍历多个可迭代对象,将它们的对应元素组合在一起。
zip 函数的基本语法如下:
zip(*iterables)
*iterables
是一个或多个可迭代对象(如列表、元组等),它们将被打包在一起。
zip
返回一个迭代器,每次迭代都会返回一个包含对应位置元素的元组。
以下是一个简单的例子,展示了如何使用 zip 函数:
names = ["Alice", "Bob", "Charlie"]
ages = [30, 25, 35]
for name, age in zip(names, ages):
print(f"{name} is {age} years old")
# 输出:
# Alice is 30 years old
# Bob is 25 years old
# Charlie is 35 years old
在这个例子中,zip 函数将 names 列表和 ages 列表打包在一起,然后在每次迭代中返回一个包含相应元素的元组。
PS:如果传递给 zip 的可迭代对象的长度不相等,zip 会以最短的可迭代对象的长度为准。
如果你需要将打包后的元组转换为列表,可以使用 list 函数:
zipped = list(zip(names, ages))
3. max和min
在Python中,max 和 min 是内建函数,它们分别用于找到可迭代对象中的最大值和最小值。
max(*args, key=None)
min(*args, key=None)
- args用来接收排序数据
- key 是一个可选的参数,用于指定一个函数,该函数将应用于可迭代对象的每个元素,以便确定比较的关键。默认值为 None。
简单示例
numbers = [5, 2, 8, 1, 6]
max_number = max(numbers) # 返回列表中的最大值,即 8
strings = ["apple", "banana", "cherry"]
max_string = min(strings, key=len) # 返回长度最短的字符串,即 "apple"
max和min对字典排序
d = {
'kevin': 1000,
'jerry': 30000,
'Tank': 200000,
'Oscar': 100
}
'''max和min默认情况下返回的是字典的key,也是按照key值比较的'''
# print(max(d))
# print(min(d))
def index(x):
return d[x] # 返回什么就安装什么进行比较
res=max(d, key=lambda x:d[x])
res1=min(d, key=lambda x:d[x])
print(res,res1)
4.filter
filter
是 Python 中的一个内建函数,它用于过滤可迭代对象(如列表、元组等)中的元素,返回一个由符合条件的元素组成的迭代器。
filter
的基本语法:
filter(function, iterable)
- function 是一个返回布尔值的函数,用于指定过滤条件。
- iterable 是一个可迭代对象,如列表、元组等。
- filter 将迭代 iterable 中的每个元素,并将满足条件的元素保留下来。
一个简单的例子:
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
# 定义一个函数,用于检查奇数
def is_odd(n):
return n % 2 != 0
# 使用filter筛选出奇数
odd_numbers = filter(is_odd, numbers)
# odd_numbers 是一个迭代器,包含了所有奇数
# 将迭代器转换为列表
odd_numbers_list = list(odd_numbers)
# odd_numbers_list 现在是包含奇数的列表 [1, 3, 5, 7, 9]
在这个例子中,我们定义了一个函数is_odd
,它接受一个参数并返回一个布尔值,指示参数是否为奇数。然后,我们使用 filter 函数将is_odd
应用于numbers
列表中的每个元素,保留满足条件的元素。
迭代
1. 可迭代对象(iterable)
可迭代对象(Iterable)是指那些可以被迭代(遍历)的数据集合。
一个对象如果是可迭代的,通常可以通过使用for
循环来遍历其中的元素。
需要注意的是,并不是所有的对象都是可迭代的。如果一个对象不是可迭代的,尝试使用 for 循环遍历它将会引发一个 TypeError 错误。
如果你想检查一个对象是否是可迭代的,可以使用内建的 iter() 函数:
my_object = [1, 2, 3, 4, 5]
if hasattr(my_object, '__iter__'):
print(f"{my_object} 是可迭代的")
else:
print(f"{my_object} 不是可迭代的")
这段代码中,我们使用了 hasattr() 函数来检查一个对象是否有 iter 属性,如果有,则认为它是可迭代的。
2. 迭代器对象
在Python中,迭代器(Iterator)是一个可以逐个访问元素的对象,而不需要提前知道容器的大小。迭代器对象实现了两个方法:__iter__()
和 __next__()
。
- iter() 方法返回迭代器对象本身。它通常在类的构造函数中实现,并返回一个具有 next() 方法的对象。
- next() 方法返回容器的下一个值。如果没有更多的项可用,则引发 StopIteration 异常。
内置有__iter__方法还内置有__next__方法
如何转为迭代器对象
有可迭代对象调用__iter__()方法转为迭代器对象
# res=s.__iter__() # 迭代器对象
# print(res.__next__()) # next其实就是迭代取值的,而且不依赖于索引取值
# print(res.__next__())
# print(res.__next__())
# print(res.__next__())
# print(res.__next__())
#
# res1 = l.__iter__()
# print(res1.__next__())
# print(res1.__next__())
# print(res1.__next__())
# print(res1.__next__())
# print(res1.__next__()) # 迭代取值,一旦值被取完,就会直接报错
# print(next(res1))
# print(next(res1))
# print(next(res1))
# print(next(res1))
"""
迭代器给我们提供了一种不依赖于索引取值的方式
"""
# 可迭代对象调用多次__iter__方法仍然是迭代器对象
# print(res.__iter__().__iter__().__iter__())
#### 易错题
l = [1, 2, 3, 4]
print(l.__iter__().__next__()) # 1
print(l.__iter__().__next__()) # 1
print(l.__iter__().__next__()) # 1
print(l.__iter__().__next__()) # 1
res = l.__iter__()
print(res.__next__()) # 1
print(res.__next__()) # 2
print(res.__next__()) # 3
print(res.__next__()) # 4
3. for循环原理
for循环内部的原理:
- 首先把关键字in后面的可迭代对象转为迭代器对象
- while循环取值__next__迭代取值,当next取值完毕的时候会报错
- 当内部报错的时候,for循环进行了异常捕捉
l = [1, 2, 3, 4, 5, 6, 7, 8, 9] # 循环打印出列表中每一个元素值,但是不能使用for循环
l = [1, 2, 3, 4, 5, 6, 7, 8, 9] # 循环打印出列表中每一个元素值,但是不能使用for循环
# count=0
# while True:
# print(l[count])
# count+=1
# res=l.__iter__()
# while True:
# print(res.__next__())
'''for循环为什么不报错呢'''
# for i in l:
# print(i)
res=l.__iter__()
while True:
try:
print(res.__next__())
except:
break
异常捕获
什么是异常:
异常就是错误发生的信号,如果不对该信号做处理,那么,异常发生的位置之后的代码都不能正常运行
异常的信息:
- Traceback:追踪信息,异常发生的位置
File “D:/Python27/day17/05 for循环内部原理.py”, line 21, in
# 有时候错误发生的信息可能会有很多行,你就找最后一行,然后点击可以跳转到错误发生的位置- XXXError: 异常发生的类型
NameError KeyError …- 错误发生的详细信息(最重要的:一般情况从这里就可以知道错位发生的原因)
name ‘a’ is not defined
异常的分类:
- 语法错误
是代码运行过程中一开始就不允许的,只要语法错误,代码一定是不能够运行的
通过代码提示就知道语法错误的原因
2. 逻辑错误
在编码过程中,逻辑错误是允许出现的
但是我们应该尽量避免逻辑错误出现的可能性
异常如何进行捕捉
try:
l = [1, 2, 3]
print(l[4]) # IndexError
# d = {'a':1}
# print(d['b'])
# 1/0
# except NameError as e:
# print(e)
# except KeyError as e:
# print(e)
# except IndexError as e:
# print(e) # list index out of range
# except ZeroDivisionError as e:
# print(e)
except Exception as e:
print(e)
else:
# 当被检测的代码没有异常的时候会走这个语法
print('这是else语法') # 这是else语法
finally:
# 不管被监测的代码是否有异常都会走
print('这是finally语法')
print(123)
"""
只能当你的被监测代码可能会出现,但是,又不想让它报错,这个时候使用异常捕捉是最合适的
异常捕捉的代码尽量少的写
"""
l = [1,2,3,4,5,6,7]
res= l.__iter__()
while True:
try:
print(res.__next__())
except Exception:
break