1。易重构 本节对一些Python重整的操作进行对比。1。1有放回随机样本和无放回随机样本 私信小编01即可获取大量python学习资源随机导入random。choices(seq,k1)长度为k的列表,有放回采样random。sample(seq,k)长度为k的列表,无放回采样1。2lambda函数的参数funclambday:xyx的值在函数运行时被绑定funclambday,xx:xyx的值在函数定义时被绑定1。3拷贝与深拷贝importcopyycopy。copy(x)只复制最速ycopy。deepcopy(x)复制所有隐藏部分 复制和变量结合时,容易重新组合:a〔1,2,〔3,4〕〕别名。baliasa断言baliasa并且balias是一个浅拷贝。bshallowcopya〔:〕断言bshallowcopy一个和bshallowcopy就是不一个和bshallowcopy〔2〕是一个〔2〕深拷贝。导入副本bdeepcopycopy。deepcopy(a)断言bdeepcopy一个和bdeepcopy就是不一个和bdeepcopy〔2〕是不一个〔2〕 对异名的修改影响原变量,(浅)复制中的元素是列表中的元素,而原变量是还原的进行复制,对还原的修改不影响原变量。1。4和是xy两引用对象是否有相同的值x是y两引用是否关联对象1。5判断类型type(a)int忽略面向对象设计中的多态特征isinstance(a,int)考虑了面向对象设计中的多态特征1。6字符串搜索str。find(sub,startNone,endNone);str。rfind(。。。)如果找不到返回1str。index(sub,startNone,endNone);str。rindex(。。。)如果找不到抛出ValueError异常1。7List后向索引 这个只是习惯问题,前向索引时下标从0开始,如果反向索引也想从0开始可以使用。print(a〔1〕,a〔2〕,a〔3〕)print(a〔0〕,a〔1〕,a〔2〕)2。CC用户使用指南 不少Python的用户是从以前CC迁移过来的,这两种语言在语法、代码风格等方面有些不同,本节简要进行介绍。2。1很大的数和很小的数 CC的习惯是定义一个很大的数字,Python中有inf和inf:afloat(inf)bfloat(inf)2。2布尔值 CC的习惯是使用0和非0值表示True和False,Python建议直接使用True和False表示布尔值。aTruebFalse2。3判断为空 CC对空指针判断的习惯是if(a)和if(!a)。Python对于None的判断是:ifxisNone:pass 如果使用ifnotx,则会将其他的对象(比如长度为0的字符串、列表、元组、字典等)都会被当做False。2。4交换值 CC的习惯是定义一个临时变量,用来交换值。利用Python的Tuple操作,可以一步到位。a,bb,a2。5比较 CC的习惯是用两个条件。利用Python可以一步到位。if0a5:pass2。6类成员的Set和Get CC的习惯是把类成员设为private,通过一系列的Set和Get函数存取其中的值。在Python中虽然也可以通过property、setter、deleter设置对应的Set和Get函数,我们应避免不必要的抽象,这会比直接访问慢45倍。2。7函数的输入输出参数 CC的习惯是把输入输出参数都列为函数的参数,通过指针改变输出参数的值,函数的返回值是执行状态,函数调用方对返回值进行检查,判断是否成功执行。在Python中,不需要函数调用方进行返回值检查,函数中遇到特殊情况,直接抛出一个异常。2。8读文件 相比CC,Python读文件要简单很多,打开后的文件是一个可迭代对象,每次返回一行内容。withopen(filepath,rt,encodingutf8)asf:forlineinf:print(line)末尾的会保留2。9文件路径拼接 CC的习惯通常直接用将路径拼接,这很容易出错,Python中的os。path。join会自动根据操作系统不同补充路径之间的或分隔符:importosos。path。join(usr,lib,local)2。10解析命令行选项 虽然Python中也可以像CC一样使用sys。argv直接解析命令行选择,但是使用argparse下的ArgumentParser工具更加方便,功能更加强大。2。11调用外部命令 虽然Python中也可以像CC一样使用os。system直接调用外部命令,但是使用subprocess。checkoutput可以自由选择是否执行Shell,也可以获得外部命令执行结果。importsubprocess如果外部命令返回值非0,则抛出subprocess。CalledProcessError异常resultsubprocess。checkoutput(〔cmd,arg1,arg2〕)。decode(utf8)同时收集标准输出和标准错误resultsubprocess。checkoutput(〔cmd,arg1,arg2〕,stderrsubprocess。STDOUT)。decode(utf8)执行shell命令(管道、重定向等),可以使用shlex。quote()将参数双引号引起来resultsubprocess。checkoutput(greppythonwcout,shellTrue)。decode(utf8)2。12不重复造轮子 不要重复造轮子,Python称为batteriesincluded即是指Python提供了许多常见问题的解决方案。3。常用工具3。1读写CSV文件importcsv无header的读写withopen(name,rt,encodingutf8,newline)asf:newline让Python不将换行统一处理forrowincsv。reader(f):print(row〔0〕,row〔1〕)CSV读到的数据都是str类型withopen(name,modewt)asf:fcsvcsv。writer(f)fcsv。writerow(〔symbol,change〕)有header的读写withopen(name,modert,newline)asf:forrowincsv。DictReader(f):print(row〔symbol〕,row〔change〕)withopen(name,modewt)asf:header〔symbol,change〕fcsvcsv。DictWriter(f,header)fcsv。writeheader()fcsv。writerow({symbol:xx,change:xx}) 注意,当CSV文件过大时会报错:csv。Error:fieldlargerthanfieldlimit(131072),通过修改上限解决importsyscsv。fieldsizelimit(sys。maxsize) csv还可以读以分割的数据fcsv。reader(f,delimiter)3。2迭代器工具 itertools中定义了很多迭代器工具,例如子序列工具:importitertoolsitertools。islice(iterable,startNone,stop,stepNone)islice(ABCDEF,2,None)C,D,E,Fitertools。filterfalse(predicate,iterable)过滤掉predicate为False的元素filterfalse(lambdax:x5,〔1,4,6,4,1〕)6itertools。takewhile(predicate,iterable)当predicate为False时停止迭代takewhile(lambdax:x5,〔1,4,6,4,1〕)1,4itertools。dropwhile(predicate,iterable)当predicate为False时开始迭代dropwhile(lambdax:x5,〔1,4,6,4,1〕)6,4,1itertools。compress(iterable,selectors)根据selectors每个元素是True或False进行选择compress(ABCDEF,〔1,0,1,0,1,1〕)A,C,E,F 序列排序:sorted(iterable,keyNone,reverseFalse)itertools。groupby(iterable,keyNone)按值分组,iterable需要先被排序groupby(sorted(〔1,4,6,4,1〕))(1,iter1),(4,iter4),(6,iter6)itertools。permutations(iterable,rNone)排列,返回值是Tuplepermutations(ABCD,2)AB,AC,AD,BA,BC,BD,CA,CB,CD,DA,DB,DCitertools。combinations(iterable,rNone)组合,返回值是Tupleitertools。combinationswithreplacement(。。。)combinations(ABCD,2)AB,AC,AD,BC,BD,CD 多个序列合并:itertools。chain(iterables)多个序列直接拼接chain(ABC,DEF)A,B,C,D,E,Fimportheapqheapq。merge(iterables,keyNone,reverseFalse)多个序列按顺序拼接merge(ABF,CDE)A,B,C,D,E,Fzip(iterables)当最短的序列耗尽时停止,结果只能被消耗一次itertools。ziplongest(iterables,fillvalueNone)当最长的序列耗尽时停止,结果只能被消耗一次3。3计数器 计数器可以统计一个可迭代对象中每个元素出现的次数。importcollections创建collections。Counter(iterable)频次collections。Counter〔key〕key出现频次返回n个出现频次最高的元素和其对应出现频次,如果n为None,返回所有元素collections。Counter。mostcommon(nNone)插入更新collections。Counter。update(iterable)counter1counter2;counter1counter2counter加减检查两个字符串的组成元素是否相同collections。Counter(list1)collections。Counter(list2)3。4带默认值的Dict 当访问不存在的Key时,defaultdict会将其设置为某个默认值。importcollectionscollections。defaultdict(type)当第一次访问dict〔key〕时,会无参数调用type,给dict〔key〕提供一个初始值3。5有序Dictimportcollectionscollections。OrderedDict(itemsNone)迭代时保留原始插入顺序4。高性能编程和调试4。1输出错误和警告信息 向标准错误输出信息importsyssys。stderr。write() 输出警告信息importwarningswarnings。warn(message,categoryUserWarning)category的取值有DeprecationWarning,SyntaxWarning,RuntimeWarning,ResourceWarning,FutureWarning 控制警告消息的输出pythonWall输出所有警告,等同于设置warnings。simplefilter(always)pythonWignore忽略所有警告,等同于设置warnings。simplefilter(ignore)pythonWerror将所有警告转换为异常,等同于设置warnings。simplefilter(error)4。2代码中测试 有时为了调试,我们想在代码中加一些代码,通常是一些print语句,可以写为:在代码中的debug部分ifdebug:pass 一旦调试结束,通过在命令行执行O选项,会忽略这部分代码:python0main。py4。3代码风格检查 使用pylint可以进行不少的代码风格和语法检查,能在运行之前发现一些错误pylintmain。py4。4代码耗时 耗时测试pythonmcProfilemain。py 测试某代码块耗时代码块耗时定义fromcontextlibimportcontextmanagerfromtimeimportperfcountercontextmanagerdeftimeblock(label):ticperfcounter()try:yieldfinally:tocperfcounter()print(s:s(label,toctic))代码块耗时测试withtimeblock(counting):pass 代码耗时优化的一些原则专注于优化产生性能瓶颈的地方,而不是全部代码。避免使用全局变量。局部变量的查找比全局变量更快,将全局变量的代码定义在函数中运行通常会快1530。避免使用。访问属性。使用frommoduleimportname会更快,将频繁访问的类的成员变量self。member放入到一个局部变量中。尽量使用内置数据结构。str,list,set,dict等使用C实现,运行起来很快。避免创建没有必要的中间变量,和copy。deepcopy()。字符串拼接,例如a‘:’b‘:’c会创造大量无用的中间变量,’:’,join(〔a,b,c〕)效率会高不少。另外需要考虑字符串拼接是否必要,例如print(’:’。join(〔a,b,c〕))效率比print(a,b,c,sep’:’)低。5。Python其他技巧5。1argmin和argmaxitems〔2,1,3,4〕argminmin(range(len(items)),keyitems。getitem) argmax同理。5。2转置二维列表A〔〔a11,a12〕,〔a21,a22〕,〔a31,a32〕〕Atransposelist(zip(A))listoftupleAtransposelist(list(col)forcolinzip(A))listoflist5。3一维列表展开为二维列表A〔1,2,3,4,5,6〕Preferred。list(zip(〔iter(A)〕2))