流畅的python 函数
列表推导:
通常只用列表推到来创建新的列表,且尽量简短,它的作用只有一个,就是生成列表,生成其他序列就要用到生成器表达式了。
a = range(10) b = [x*x for x in a] # 列表推导式 print(b)
生成器表达式:
虽然列表推导可以创建元组,数组,或其他序列类型,但生成器表达式是更好的选择。生成器表达式背后遵循了迭代器协议,可以逐个的产出元素,而不是先建立一个完整的列表。写法与列表推导式非常的相似:
# 生成器表达式 a = range(10) b = (x*x for x in a) # 生成器表达式 print(tuple(b))
列表推导与生成器表达式对比:
colors = ['white', 'black', 'red'] sizes = ['S', 'M', 'L'] # 列表推导 for x in [(color, size) for color in colors for size in sizes]: print(x) # 生成器表达式 for x in ((color, size) for color in colors for size in sizes): print(x)
用了声称其表达式后,内存里不会留下一个有9个组合的列表,因为生成器表达式只有每次执行for循环时才会产生一个元素。
但是列表推导首先会新建一个列表。
将函数视作对象:
# 定义函数 def factorial(n): """ 定义函数计算n的阶乘 :param n: :return: """ return 1 if n<2 else n*factorial(n-1) # 将函数视作对象 fact = factorial print(fact(10)) # 函数作为参数传递 a = range(10) b = map(factorial, a) print(list(b))
高阶函数:接收函数为参数或者将函数作为结果返回的函数叫做高阶函数,例如map()函数
tp = ["apple", 'peaches', 'holland', 'newspaper_stand'] tpp = sorted(tp, key=lambda x: len(x)) print(tpp) def reverse(word): """ 逆序输出 :param word: :return: """ return word[::-1] tpp = map(reverse, tp) print(list(tpp))
常用的高价函数:map(), filter(), reduce(),函数式语言通常会提供这三个高阶函数
for x in map(factorial, range(10)): print(x) for x in filter(lambda x: x % 2 == 0, range(20)): print(x)
python3中map(),filter()函数返回的是生成器!
from functools import reduce from operator import add # add(x,y)函数 print(reduce(add, range(100)))
sum(), reduce()函数的通用思想是把某个操作连续运用到序列的元素上,累计之前的结果,把一系列值规约为一个值
all(iter), any(iter)函数
匿名函数:
lambda表达式。一般作为参数传递给高阶函数
可调用对象:
判断对象是否可调用print(callable(factorial))
python数据模型指出七种可调用的类型:
1.用户自定义函数 def
2.内置函数
3. 内置方法
4. 方法 类中定义的函数
5. 类
6. 类的实例
7. 生成器函数
从定位参数到仅限关键字参数:
python提供了极为灵活的参数处理机制:调用*和**展开可迭代对象,映射到单个参数
def tag(name, *content, cls=None, **attrs): if cls is not None: attrs['class'] = cls if attrs: attr_string = " ".join(' %s="%s"' % (key, value) for key, value in attrs.items()) else: attr_string = '' if content: return '\n'.join('<%s%s>%s<%s>' % (name, attr_string, c, name) for c in content) else: return '<%s%s />' % (name, attr_string)
对函数的调用:
print(tag("br")) # 传入单个定位参数 print("-"*30) print(tag('p', 'hello')) # 第一个后面的人一个参数会被content捕获,存入元组 print('-'*30) print(tag('p', 'hello', 'world')) # 第一个后面的人一个参数会被content捕获,存入元组 print('-'*30) print(tag('p', 'hello', 'world', cls='sidebar')) # cls只能作为关键字参数传入 print('-'*30) print(tag('p', 'hello', 'world', id=23, href='http://sina.com', cls='sidebar'))
调用的结果:(函数的参数收集)
operator模块:
operator模块为多个算术运算符提供了对应的函数,从而避免在一些地方写匿名函数:
例如计算阶乘:
from functools import reduce def fact1(n): return reduce(lambda x, y: x*y, range(1, n+1)) print(fact1(10))
为了避免写lambda这样的匿名函数:
from functools import reduce from operator import mul def fact1(n): return reduce(mul, range(1, n+1)) print(fact1(10))
operator模块中itemgetter和attrgetter函数:能替代从元素中取出元素或者读取对象属性的lambda表达式:
lambda x: x[n] 或者lambda x: x["attr"]
例如:
person_data = [('Ann', 34, 'boy', 'student'), ('Tom', 23, 'boy', 'doctor'), ('Liky', 21, 'girl', 'sailor'), ('Kate', 19, 'girl', 'queen')] for x in sorted(person_data, key=lambda x: x[1]): print(x)
可以写为:
from operator import itemgetter person_data = [('Ann', 34, 'boy', 'student'), ('Tom', 23, 'boy', 'doctor'), ('Liky', 21, 'girl', 'sailor'), ('Kate', 19, 'girl', 'queen')] for x in sorted(person_data, key=itemgetter(1)): print(x)
输出结果:
将多个值传递给itemgetter,它构建的函数会返回提取的值构成的元组:
from operator import itemgetter cc_person = itemgetter(0, 2, 3) person_data = [('Ann', 34, 'boy', 'student'), ('Tom', 23, 'boy', 'doctor'), ('Liky', 21, 'girl', 'sailor'), ('Kate', 19, 'girl', 'queen')] for x in person_data: print(cc_person(x))
返回值:
attrgetter和itemgetter函数类似,它创建的函数根据名称提取对象的属性,同样也可以将多个属性传递给它:
这里会用到具名元组namedtuple:
from operator import itemgetter from operator import attrgetter from collections import namedtuple person_data = [('Ann', 34, 'boy', 'student', (23.4, 90.5)), ('Tom', 23, 'boy', 'doctor', (12.3, 56.1)), ('Liky', 21, 'girl', 'sailor', (21.8, 98.1)), ('Kate', 19, 'girl', 'queen', (32.1, 89))] LatLong = namedtuple('LatLong', ['lat', 'long']) # fieldname参数可以是列表 people = namedtuple('people', 'name age sex occupation coord') # feildname参数也可以是这样 people_list = [people(name, age, sex, occupation, LatLong(lat, long)) for (name, age, sex, occupation, (lat, long)) in person_data] # 具名元组的访问 print(people_list[0]) print('-'*30) print(people_list[1].occupation) # 通过 . 运算符访问具名元组的元素 print('-'*30) print(people_list[2].coord.long) print('-'*30) for x in sorted(people_list, key=attrgetter('age')): print(x) print('-'*30) name_lat = attrgetter('name', 'coord.lat') for x in sorted(people_list, key=attrgetter('age')): print(name_lat(x))
注意具名元组的使用!
运行结果:
methodcaller()函数,会在对象上调用参数值指定的方法:
from operator import methodcaller s = 'hello world' uppercase = methodcaller('upper') print(uppercase(s)) replacement = methodcaller('replace', ' ', '-') print(replacement(s))
functools.partial冻结参数:
# 冻结tag()函数的部分参数 from functools import partial picture = partial(tag, 'img', cls='pic-frame') # 冻结tag()函数的定位参数以及cls参数 print(picture('pict1', 'pict2')) print('-'*30) print(picture('pict1', 'pict2', src='www.xxx.com'))
partial函数对于函数的部分参数进行了冻结,再调用的我们只需要关心我们需要改变的参数即可
--------------------------------------------------------------------------------------------------
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)