本次分享是关于Python生态系统中的一些有用的技能。大多数技巧只使用标准库中的包,但其他一些技巧涉及一些第三方包。在开始阅读本文内容之前,我们先来回顾一下Python中Iterables的概念。根据Python标准文档,Iterable的概念是这样的:一个能够一次返回一个成员的对象。iterables的例子包括:所有的序列类型(比如list,str,tuple)一些非序列类型,比如dict,file对象,类实现定义了__iter__()方法Iterables是我们需要保留的一个概念请注意,因为以下我们展示的许多技巧都使用了itertools包。itertools模块提供了接收Iterable对象的功能,而不是仅仅一个一个地打印它们。2.Trick1在工作和学习中,我们经常需要使用一个简单的函数从一个列表中生成一个新的列表、集合或字典。这个时候我们就要用到iterables的概念了。例如:GenerateList:names=['John','Bard','Jessica''Andres']lower_names=[name.lower()fornameinnames]GenerateSet:names=['John','Bard','Jessica''Andres']lower_names={name.lower()fornameinnames}生成Dict:names=['John','Bard','Jessica''Andres']lower_names={name:name.lower()fornameinnames}personRecommendation:仅在for语句、函数调用、方法调用次数较少时使用。3.Trick2有时候,我们需要得到两个列表对象之间所有可能的组合。我们首先想到的实现方式可能是:l1=[1,2,3]l2=[4,5,6]combinations=[]fore1inl1:fore2inl2:combinations.append((e1,e2))或者简化一下,如下:combinations=[(e1,e2)fore1inl1fore2inl1]上面的实现已经很简洁了,但是标准库itertools提供了product函数,结果是一样的。如下:fromitertoolsimportproductl1=[1,2,3]l2=[4,5,6]combinatios=product(l1,l2)4.Trick3假设有一个元素列表,我们需要比较每对相邻元素或者应用一些操作,有时称为2元素的滑动窗口。我们可以通过以下方式做到这一点:fromitertoolsimportteefromtypingimportIterabledefwindow2(iterable:Iterable):it,offset=tee(iter(iterable))next(offset)returnzip(it,offset)l=[1,2,3,4,5,6]dd=window2(l)foraindd:print(a)结果如下:(1,2)(2,3)(3,4)(4,5)(5,6)5.Trick4有时候,我们需要一个类来存储信息,但是如果我们觉得创建一个类并定义它的__init__()函数太麻烦,我们不妨选择使用dataclass。如下:fromdataclassesimportdataclass@dataclassclassPerson:name:strage:intaddress:str上面的代码创建了一个带有默认构造函数的类,它按照声明时的相同顺序接收对相应字段的赋值。person=Person(name='John',age=12,address='nanjingstreet')数据类的另一个优点是,默认情况下会生成特殊方法,如__str__、repr、__eq__等。对于更多用法dataclass,可以参考官网。值得一提的是,我们在类中声明的成员变量的类型注解(str、int等)并不强制构造函数中传递的值必须是该类型。也就是说,数据类在构造对象时不进行数据类型检查。6.Trick5我们有时想把对一个对象的操作当作对元组的操作。一种选择是使用collections.namedtuple,但也有更多类似数据类的实现。如下:fromtypingimportNamedTupleclassCoordinate(NamedTuple):x:inty:int上面定义了一个可以作为元组使用的标准类,如下:coordinate=Coordinate(10,15)coordinate.x==coordinate[0]//真坐标.y==coordinate[1]//True7.Trick6如果我们有一个dataclass,我们需要验证输入的数据是否符合类型注解。此时安装第三方包pydantic,将fromdataclassesimportdataclass替换为frompydantic.dataclassesimportdataclass,如下:frompydantic.dataclassesimportdataclass@dataclassclassPerson:name:strage:intaddress:str这样会生成一个类,这个类有根据成员变量的声明类型对输入数据进行分析和类型验证。Pydantic在运行时强制执行类型提示,并在数据无效时提供友好的错误通知。8.Trick7在某些情况下,我们需要生成一些容器中元素出现频率的基本统计信息。在这种情况下,您可以使用标准的structCounter来接收一个可迭代对象,并根据元素的频率生成相应的统计信息。fromcollectionsimportCounterl=[1,1,2,3,4,4]frequencys=Counter(l)print(frequencys[1])//Ouput:2print(frequencys[2])//Ouput:1print(frequencys[2323])//Ouput:0Counter还提供了一些其他的方法,比如most_common,用于检索最常见的元素。9.Trick8如果我们对两个列表中的元素对进行相应的函数处理,我们能想到的最简单的方法如下:l1=[1,2,3]l2=[4,5,6]for(e1,e2)inzip(l1,l2):f(e1,e2)但是使用函数映射可以让代码更加简洁。l1=[1,2,3]l2=[4,5,6]map(f,l1,l2)10.Trick9有时我们需要从列表中随机选择一个元素,这时候我们使用random.choice。如下图:fromrandomimportchoicel=[1,2,3]random=choice(l)如果我们需要随机选择多个元素怎么办?当然使用random.choices.fromrandomimportchoicesl=[1,2,3,4,5]random_elements=choices(l,k=3)上面代码中的参数k就是我们随机选择的元素个数。11.小结本文重点介绍python中九个迭代相关的使用技巧,可以轻松提高大家的工作效率。你失学了吗?
