本文转载自公众号“阅读核心”(ID:AI_Discovery)各个学科和行业都在经历一场“Python热潮”。笔者在观察了Python编程在生物医学领域的使用情况后,发现相当多的Python程序员有着不同的编程经验,如Matlab、C语言、C++、Java、JavaScript、Swift等,也有一些完全没有编程经验的。有经验的人。Python已经成为程序员的“外语”。他们可能没有接受过系统的Python编码培训,也可能不知道Python开发的惯用方法。虽然程序员仍然可以通过不同的方式实现同??样的功能,写出优秀的代码,但是只要代码能够达到预期的目的,就OK了。编写非惯用的Python程序也没有问题。但就在我们不断练习自己的英语口音的同时,一些人也想让他们的Python代码更加地道。在这篇文章中,我将分享我这几年积累的一些习语,希望能帮助大家提高Python编码水平。1.拆分序列常见的序列类型包括列表、元组和字符串。通过拆分另一个序列,可以创建一个新序列。以下函数使用列表作为示例,但它们也可用于其他序列类型,例如元组、字符串和字节。>>>a=[0,2,4,6,8,10,12,14,16,18,20]>>>#Usingarange,[开始,结束)>>>a[1:3][2,4]>>>#Usingarangewithstep>>>a[1:9:2][2,6,10,14]>>>#Leaveoutthestart=animplicitstartof0>>>a[:5][0,2,4,6,8]>>>#Leaveoutthestop=animplictendtotheverylastitem>>>a[9:][18,20]>>>#Entirelist>>>a[:][0,2,4,6,8,10,12,14,16,18,20]2.使用反向索引访问序列中的元素如果要访问序列末尾的某些元素,那么反向计数要容易得多。在Python序列中,最后一个元素的索引为-1,倒数第二个元素的索引为-2,依此类推。>>>a='HelloWorld!'>>>#insteadofusinga[len(a)-1]>>>a[-1]'!'>>>#incombinationwithslicing>>>a[-5:-1]'世界'3。多重赋值当给几个变量赋值时可以使用多重赋值。通过相同的习惯用法,可以交换同一个列表中的两个变量或两个元素。这个特性和后面要介绍的元组拆包密切相关。>>>#insteadofdoinga=8;b=5>>>a,b=8,5>>>print(f'ais{a};bis{b}')ais8;bis5>>>#Swaptwovariables>>>a,bb=b,a>>>print(f'ais{a};bis{b}')ais5;bis8>>>#Swapthefirstandlastelementsinalist>>>numbers=[1,2,3,4,5]>>>numbers[0],numbers[-1]=numbers[-1],numbers[0]>>>numbers[5,2,3,4,1]4.颠倒顺序有时需要颠倒顺序顺序。虽然可以用for循环语句来实现,但是还有更简单直接的方法。与上面类似,当一个特征可用于序列时,通常意味着字符串、元组和列表也都支持该特征。>>>a=(1,2,3,4,5)>>>a[::-1](5,4,3,2,1)>>>b='开始'>>>b[::-1]'trats'5。检查序列是否为空只有当序列不为空时,列表、元组等操作才会起作用,所以在操作前需要检查序列是否为空。>>>empty_list=[(),'',[],{},set()]>>>foriteminempty_list:...ifnotitem:...print(f'Dosomethingwiththe{type(item)}')...DosomethingwiththeDosomethingwiththeDosomethingwiththeDosomethingwiththeDosomethingwiththe为此,您可以使用not关键字对序列求反(例如not[]),只要序列不为空,它的计算结果为True。此外,还可以对另外两种常见的数据类型dict和set进行同样的操作。6.集合推导集合推导的用法与上面列表推导的用法类似。不同之处在于集合推导使用花括号而不是方括号。此外,通过定义集合数据类型,可以删除重复元素。7.字典生成除了列表推导和集合推导之外,解析特征也可以用来创建字典数据类型。字典由键值对组成,因此字典理解包含指定的键和值,用冒号分隔。>>>a=[1,2,3,4,5]>>>{x:x*xforxina}{1:1,2:4,3:9,4:16,5:25}8.generatePython中的生成器是创建迭代器的便捷方式。因为生成器是“惰性的”(即只有在发出请求时才生成需要的项目)。生成器的内存效率很高。一种创建生成器的特殊方法称为生成器表达式。生成器表达式在句法上类似于列表理解,只是它们使用圆括号而不是方括号。在下面的示例中,当在迭代器函数中直接使用生成器时,括号是可选的。>>>sum(x**2forxinrange(100))328350>>>max((x*xforxinrange(100)))98019。列表推导式Python中一个有用的特性是列表推导式。使用列表推导式,您可以轻松构建列表。列表理解的一般形式是[some_expressionforelementiterableifsome_condition]。>>>a=[1,2,3,4,5]>>>[x*2forxina][2,4,6,8,10]>>>[x*3forxinaifx%2==1][3,9,15]10.拆包元组元组是Python中非常常见的数据结构。它们是相关值的组。元组的常见用途包括访问它们自己的元素。虽然可以使用索引访问这些元素,但解包是一种更方便的方法。与拆包的用法相关,可以用下划线表示不需要的元素,用星号给命名元素以外的元素赋值。>>>items=(0,'b','one',10,11,'zero')>>>a,b,c,d,e,f=items>>>print(f)zero>>>a,*b,c=items>>>print(b)['b','one',10,11]>>>*_,a,b=items>>>print(a)1111。在for循环语句中使用Reversed()函数reversed()函数通常用在for循环语句中,是一种以与原始可迭代对象相反的顺序创建迭代器的方法。>>>tasks=['laundry','pickingupkids','gardening','cooking']>>>fortaskinreversed(tasks):...print(task)...cookinggardeningpickingupkidslaundry12。Zip()压缩函数zip()函数对于通过一对一匹配连接多个迭代器很有用。如果超过最短迭代器,一些迭代器将被截断。zip()函数返回一个迭代器,因此经常在迭代中使用。您还可以使用zip()函数解压缩带星号的迭代器并将未压缩的项分配给变量。>>>students=('John','Mary','Mike')>>>ages=(15,17,16)>>>scores=(90,88,82,17,14)>>>forstudent,age,scoreinzip(students,ages,scores):...print(f'{student},age:{age},score:{score}')...John,age:15,score:90Mary,age:17,score:88Mike,age:16,score:82>>>zipzipped=zip(students,ages,scores)>>>a,b,c=zip(*zipped)>>>print(b)(15,17,16)13。使用Lambdas将lambdas表达式排序为匿名函数,可以在单行表达式中接收多个参数。lambda的一个常见用途是将它们设置为内置sorted()函数中的关键参数。此外,lambdas经常用在max()和map()等函数中。在这些函数中,可以使用单行表达式代替使用def关键字的常规函数??。>>>students=[{'name':'John','score':98},{'name':'Mike','score':94},{'name':'Jennifer','score':99}]>>>sorted(students,key=lambdax:x['score'])[{'name':'Mike','score':94},{'name':'John','score':98},{'name':'Jennifer','score':99}]14.简写条件赋值这个特性基本上是语法糖。当根据特定条件为变量赋值时,可以使用以下通用速记赋值:y=xifcondition_metelseanother_x。>>>some_condition=True>>>#theexpandedformat>>>ifsome_condition:...x=5...else:...x=3>>>print(f'xis{x}')xis5>>>#theshorthandway>>>x=5ifsome_conditionelse3>>>print(f'xis{x}')xis515。在for循环语句中使用Enumerate()枚举函数,使用enumerate()函数获取可迭代对象来创建迭代器。此外,enumerate()函数会跟踪迭代次数。计数的初始值可以任意设置。默认计数初始值为0。>>>students=('John','Mary','Mike')>>>fori,studentinenumerate(students):...print(f'Iteration:{i},Student:{student}')..Iteration:0,Student:JohnIteration:1,Student:MaryIteration:2,Student:Mike>>>fori,studentinenumerate(students,35001):...print(f'StudentName:{student},StudentID#:{i}')...StudentName:John,StudentID#:35001StudentName:Mary,StudentID#:35002StudentName:Mike,StudentID#:3500316。使用Get()方法检索字典中的值通常,您可以在方括号中指定键来检索键的值。但是,当键不在字典中时,可能会发生错误。当然也可以使用try/except异常处理机制来解决这个问题。但是,当键不在字典中时,也可以通过get()方法设置默认值。>>>number_dict={0:'zero',1:'one',2:'two',3:'three'}>>>number_dict[5]Traceback(mostrecentcallast):File"",line1,在<模块>KeyError:5>>>number_dict.get(5,'five')'five'17.获取字典中最大值对应的key有时需要在字典中找到最大值对应的key。首先在所有值的列表中找到最大值的索引,然后从另一个存储所有键的列表中找到对应的键。或者,也可以使用更简单的方法,就是在max()函数中指定key参数。为了简洁起见,不考虑最大值的可能重复。同样,你也可以使用min()函数来找到最小值对应的key。>>>model_scores={'model_a':100,'model_z':198,'model_t':150}>>>#workaround>>>keys,values=list(model_scores.keys()),列表(model_scores.values())>>>keys[values.index(max(values))]'model_z'>>>#one-line>>>max(model_scores,key=model_scores.get)'model_z'18。使用Print()函数进行调试对于较小的项目,可以使用print()函数进行调试。这个功能在教学中也经常用到。在print()函数中,经常会用到一些技巧。第一种是结束字符串而不是默认的换行符;第二种是使用字符串f-string,创建一个包含一些表达式的字符串。>>>foriinrange(5):...print(i,end=','ifi<4else'\n')...0,1,2,3,4>>>foriinrange(5):...print(f'{i}&{i*i}',end=','ifi<4else'\n')...0&0,1&1,2&4,3&9,4&1619。集合元素存在性测试有时,在对集合或匹配项进行操作之前,需要测试某个元素是否存在于集合中。惯用的方法是使用关键字in。>>>a=('one','two','three','four','five')>>>if'one'ina:...print('元组包含一个。')...元组包含一个。>>>b={0:'零',1:'一',2:'二',3:'三'}>>>if2inb.keys():...print('Thedicthasthekeyof2.')...Thedicthasthekeyof2.20。海象运算符海象运算符(:=)是Python3.8版中的一项新功能。它只是赋值表达式的另一个名称(在表达式中为变量赋值)。一般来说,在表达式中使用变量时,必须提前声明变量。使用海象运算符,可以在表达式中包含变量赋值,并且可以立即使用该变量。>>>a=['j','a','k','d','c']>>>if(n:=len(a))%2==1:...print(f'Thenumberoflettersis{n},whichisodd.')...Thenumberoflettersis5,whichisodd.21.拆分字符串在处理字符串时,通常会将字符串拆分为单词列表。这种情况下可以使用split()函数的定界符,最大定界符是可选的。相关的函数是rsplit()函数,它和split()函数类似,只是设置时从右边开始拆分,以满足最大拆分要求。>>>sentence='thisis,apython,tutorial,about,idioms.'>>>sentence.split(',')['thisis','apython','tutorial','about','idioms.']>>>sentence.split(',',2)['thisis','apython','tutorial,about,idioms.']>>>sentence.rsplit(',')['thisis','apython','tutorial','about','idioms.']>>>sentence.rsplit(',',2)['thisis,apython,tutorial','about','idioms.']22.Map()map()函数是高阶函数(即,将函数作为参数或返回值作为其输出的函数)。它的一般格式是map(function,iterables)。map()函数将一个可迭代对象作为参数并返回一个映射对象,而映射对象又是一个迭代器。可迭代对象的数量应与函数所需的参数数量相匹配。在下面的示例中,内置函数pow()有两个参数。当然也可以使用自定义函数。顺便说一句,在使用map()函数创建列表时,使用列表理解应该可以达到相同的效果。>>>numbers=(1,2,4,6)>>>indices=(2,1,0.5,2)>>>#usemap()>>>list(map(pow,numbers,indices))[1,2,2.0,36]>>>#listcomprehensions>>>[pow(x,y)forx,yinzip(numbers,indices)][1,2,2.0,36]23。Filter()过滤函数filter()函数使用指定的函数或lambda函数过滤一个序列。该函数返回一个过滤器对象,它是一个迭代器。总的来说,这个函数的用法与m??ap()函数非常相似。>>>defgood_word(x:str):...has_vowels=notset('aeiou').isdisjoint(x.lower())...long_enough=len(x)>7...good_start=x.lower().startswith('pre')...returnhas_vowels&long_enough&good_start...>>>words=['Good','Presentation','preschool','prefix']>>>list(filter(good_word,words))['演示文稿','学前班']24。在可迭代对象中连接字符串在处理字符串时,有时需要通过在可迭代对象(如列表、元组等)中连接一系列字符串来创建单个字符串。在这种情况下,可以调用join()函数所需的分隔符。>>>words=('你好','Python','程序员')>>>'!'.join(words)'你好!Python!程序员'>>>words_dict={0:'零',1:'一',2:'二',3:'三'}>>>'&'.join(words_dict.values())'零&一&二&三'25。Findthemostcommonelementsinthelist记录一些在列表元素中有重复的元素,比如跟踪一系列游戏的获胜者,这与找到哪个玩家获胜次数最多有关。可以通过max()函数指定key参数,对集合中的元素进行计数,找出最大值。>>>winnings=['John','Billy','Billy','Sam','Billy','John']>>>max(set(winnings),key=winnings.count)'Billy'26.检查对象类型检查对象类型是Python内省功能的一部分。有时在应用相应的功能之前需要知道一个对象是否属于某种类型。因此,可以使用type()函数或者isinstance()函数,更加灵活,可以进行一对多的测试。>>>defcheck_type(number):...iftype(number)==int:...print('dosomethingwithanint')...ifisinstance(number,(int,float)):...print('dosomethingwithanintorfloat')...>>>check_type(5)dosomethingwithintdosomethingwithanintorfloat>>>check_type(4.2)dosomethingwithanintorfloat27。Any()函数假设有一个记录列表,记录了约翰到达工作地点的时间。如果你想知道他这周有没有迟到,使用any()函数非常方便。如果布尔列表中的任何元素为True,any()函数将返回True。>>>arrival_hours={'Mon':8.5,'Tue':8.75,'Wed':9,'Thu':8.5,'Fri':8.5}>>>arrival_checks=[x>8.75forxinarrival_hours.values()]>>>任何(arrival_checks)True28。追踪列表中元素出现的频率如果你还想知道非冠军??选手在比赛中的表现如何,根据上面的例子,你可以知道第二名和第三名选手的情况。为此,您需要找出每个玩家的奖励。您可以将字典构建和sorted()函数与lambda函数结合使用。>>>winnings=['John','Billy','Billy','Sam','Billy','John']>>>tracked={item:winnings.count(item)foriteminset(winnings)}>>>sorted(tracked.items(),key=lambdax:x[1],reverse=True)[('Billy',3),('John',2),('Sam',1)]29.集体判断函数All()还是沿用上面的例子。如果还想知道他是否在9:30之前的一周内到达工作地点,可以使用all()函数。仅当布尔列表中的所有元素都为True时,all()函数才返回True。>>>arrival_checks_all=[x<9.5forxinarrival_hours.values()]>>>all(arrival_checks)True30。使用With关键字读取和处理文件时,需要打开文件,处理文件数据,然后关闭文件。如果文件在使用后没有关闭,一段时间后将无法读取文件。在这种情况下,with关键字非常有用。如下图,文件使用后自动关闭。>>>withopen('a_file.txt')asfile:...pass...>>>file.closedTrue本文无意详细罗列Python编程中的习语,只是想为读者提供一些常用的那些惯用的用法可以用在日常编码中。