收藏Python实用技巧.docx
《收藏Python实用技巧.docx》由会员分享,可在线阅读,更多相关《收藏Python实用技巧.docx(47页珍藏版)》请在冰点文库上搜索。
收藏Python实用技巧
【收藏】Python实用技巧
前言
本文主要记录Python中一些常用技巧,所描述的是告诉你怎么写才是更好?
如果你并不熟悉Python语法,希望你能在下面代码片段中看到Python的简单、优雅;如果你象我这样,对Python有兴趣或并正在学习,我相信下面的技巧并不会让你失望;如果你已经是一名Pythoner,那么很乐于你分享你的经验和技巧。
Python禅道
代码风格:
提高可读性
PEP8:
Python代码风格指南
空格(行)使用
(1)
空格(行)使用
(2)
命名
较长代码行
较长字符串
复合语句
字符串文档&注释
交换变量
更多关于Tuples
关于"_"
创建String:
从列表中创建
尽可能的使用
字典中的get函数
字典中的setdefault函数
(1)
字典中的setdefault函数
(2)
defaultdict
创建&分割字典
判断True值
True值
索引&项
(1)
索引&项
(2):
enumerate
默认参数值
列表理解
生成器表达式
(1)
生成器表达式
(2)
排序
使用DSU*排序
使用Key排序
生成器
生成器示例
从文件中读取数据行
try/except示例
导入(Importing)
模块&脚本
模块结构
命令行处理
简单比复杂好
不要重新发明轮子
章节
Python禅道
这是Python的指导原则,但有不同诠释。
如果您使用的一种编程语言是以小品喜剧艺术团命名的,你最好有幽默感。
美丽优于丑陋。
明确优于含蓄。
简单比复杂好。
平倘优于嵌套。
稀疏比密集更好。
特殊情况不能特殊到打破规则。
错误不应该默默传递。
......
代码风格:
提高可读性
Programsmustbewrittenforpeopletoread,andonlyincidentallyformachinestoexecute.
—Abelson&Sussman,StructureandInterpretationofComputerPrograms
PEP8:
Python代码风格指南
值得阅读:
http:
//www.python.org/dev/peps/pep-0008/
空格(行)使用
(1)
使用4个空格缩进。
不要使用制表符。
不要将制表符和空格混合使用。
IDEL和Emacs的Python的都支持spaces模式。
每个函数之间应该有一个空行。
每一个Class之间应该有两个空行。
空格(行)使用
(2)
在使用字典(dict),列表(list),元组(tuple),参数(argument)列表时,应在","前添加一个空格,并且使用字典(dict)时,在":
"号后添加空格,而不是在前面添加。
在括号之前或参数之前不添加空格。
在文档注释中前后应该没有空格。
Python代码
defmake_squares(key,value=0):
"""Returnadictionaryandalist..."""
d={key:
value}
l=[key,value]
returnd,l
命名
joined_lower可以是函数名,方法名,属性名
joined_lowerorALL_CAPS是常量
StudlyCaps类名
camelCase只有在预先制定好的命名规范使用
属性:
interface,_internal,__private
但尽量避免__private形式。
下面两个链接解释了为什么python中没有private声明?
较长代码行
保持一行代码在80个字符长度。
在括号内使用隐含的行延续:
Python代码
def__init__(self,first,second,third,
fourth,fifth,sixth):
output=(first+second+third
+fourth+fifth+sixth)
或者在需要换行的位置使用\来延续行:
Python代码
VeryLong.left_hand_side\
=even_longer.right_hand_side()
另外,使用反斜杠是有风险的,如果你添加一个空格在反斜杠后面,它就出错了。
此外,它使代码难看。
较长字符串
将相邻的字符串进行连接的做法:
Python代码
>>>print’o’’n’"e"
one
虽然字符之间的空格不是必需的,但是这样有助于可读性。
Python代码
>>>print’t’r’\/\/’"""o"""
t\/\/o
用一个“r“开头的字符串是一个“raw“的字符串(类似java中的转义符)。
上面的反斜杠就会当成普通字符串处理。
他们对正则表达式和Windows文件系统路径非常有用。
dsyntax
这是因为自动连接是由Python解析器/编译器来处理的,因为其无法在编译时对变量值进行"翻译",所以就这种必须在运行时使用“+“运算符来连接变量。
复合语句
Good:
Python代码
iffoo==‘blah’:
do_something()
do_one()
do_two()
do_three()
Bad:
Python代码
iffoo==‘blah’:
do_something()
do_one();do_two();do_three()
文档注释(Docstrings)&注释
文档注释=用于解释如何使用代码
文档注释公约:
http:
//www.python.org/dev/peps/pep-0257/
注释=为什么(理由)&代码如何工作的如:
Python代码
#!
!
!
BUG:
...
#!
!
!
FIX:
Thisisahack
#?
?
?
Whyisthishere?
注释对于任何语言开发者来说已经最基本的东西了,这里就不详细说了.
交换变量
在其它语言的交换变量的做法一般是:
Java代码
temp=a
a=b
b=temp
Python的做法:
Python代码
b,a=a,b
也许你见到过这样的情况,但是你知道它是如何工作的吗?
首先,逗号是元组构造语法。
等号的右边是定义一个元组(tuplepacking).
其左边为一个目标元组(tupleunpacking)).
右边的元组根据名称被unpacked到左边的无组。
更多关于unpacked例子:
Python代码
>>>info=[‘David’,’Pythonista’,’+1250’]
>>>name,title,phone=info
>>>name
‘Davids’
>>>title
‘Pythonista’
>>>phone
‘+1250’
在结构化的数据上使用循环:
info是在上面定义的一个list.所以下面的people有两个项,两个项都是分别都拥有三个项的list.
Python代码
>>>people=[info,[‘Guido’,’BDFL’,’unlisted’]]
>>>for(name,title,phone)inpeople:
...printname,phone
...
David+1250
Guidounlisted
以上循环中,people中的两个项(listitem),都已经被unpacked到(name,title,phone)无组中。
可以任意嵌套(只要左右两边的结构一定要能够匹配得上):
Python代码
>>>david,(gname,gtitle,gphone)=people
>>>gname
‘Guido’
>>>gtitle
‘BDFL’
>>>gphone
‘unlisted’
>>>david
[‘David’,’Pythonista’,’+1250’]
更多关于Tuples
我们看到的是元组通过逗号构造,而不是括号。
例如:
Python代码
>>>1,
(1,)
Python的解释器会为你显示括号,所以建议你使用括号:
Python代码
>>>(1,)
(1,)
千万不要忘记逗号!
Python代码
>>>
(1)
1
在只有一个元素的元组,尾随逗号是必须的,在2+元素的元组,尾随逗号是可选的。
如果创建一个0或空元组,一对括号是快捷的语法:
Python代码
>>>()
()
>>>tuple()
()
一个常见的错误当你并不想要一个无组,却无意的添加了一个逗号,很容易造成你在代码中的错误,如:
Python代码
>>>value=1,
>>>value#isatuple,notaint
(1,)
所以,当你发现一个元组时,赶紧去找一下那个,号吧。
关于"_"
是一个非常有用的功能,但是却很少有人知道。
当你在交互式模式下(如IDEL)计算一个表达式或调用一个函数后,其结果必然是一个临时名称,_(下划线):
Python代码
>>>1+1
2
>>>_
2
在_中存储最后输出的值。
当输出的结果是None或没有任何输出时,而_的值并不会改变,仍然保存上一次的值。
这就是方便所在。
当然,这只能交互式的模式中使用,在模块中不能支持。
这在交互式模式中是非常有用的,当你在过程中没有保存计算结果或你想看最后一步的执行的输出结果:
Python代码
>>>importmath
>>>math.pi/3
1.0471975511965976
>>>angle=_
>>>math.cos(angle)
0.50000000000000011
>>>_
0.50000000000000011
创建String:
从列表中创建
开始定义一个string列表:
Python代码
colors=[‘red’,’blue’,’green’,’yellow’]
当我们需要将上面的列表连接成一个字符串。
尤其当list是一个很大的列表时....
不要这样做:
Python代码
result=‘‘
forsincolors:
result+=s
这种方式效率非常低下的,它有可怕的内存使用问题,至于为什么,如果你是javaer的话,其中的string连接,我想你并不陌生。
相反,你应该这样做:
Python代码
result=‘‘.join(colors)
当你只有几十或几百个string项连接时,它们效率上并不会太大的差别。
但你要在养成写高效代码的习惯,因为当字符串数千时,join比起for连接性能会能有所提升。
如果你需要使用一个函数来生成一个字符串列表,同样可以使用:
Python代码
result=‘‘.join(fn(i)foriinitems)
尽可能的使用
Good:
Python代码
forkeyind:
printkey
使用in一般情况下是非常快的。
这种方式也适用于其它的容器对象(如list,tuple和set)。
in是操作符(正如上面所看到的)。
Bad:
Python代码
forkeyind.keys():
printkey
保持与上面的一致性,使用usekeyindict方式,而不是dict.has_key():
Python代码
#dothis:
ifkeyind:
...dosomethingwithd[key]
#notthis:
ifd.has_key(key):
...dosomethingwithd[key]
字典中的get函数
我们经常需要在字典中初始化数据:
以下是不好的实现方法:
Python代码
navs={}
for(portfolio,equity,position)indata:
ifportfolionotinnavs:
navs[portfolio]=0
navs[portfolio]+=position*prices[equity]
使用dict.get(key,default)删除if判断代码:
Python代码
navs={}
for(portfolio,equity,position)indata:
navs[portfolio]=(navs.get(portfolio,0)
+position*prices[equity])
这种方式更为直接。
字典中的setdefault函数
(1)
当我们要初始化一个可变字典的值。
每个字典的值将是一个列表。
下面是不好的做法:
初始化可变字典的值:
Python代码
equities={}
for(portfolio,equity)indata:
ifportfolioinequities:
equities[portfolio].append(equity)
else:
equities[portfolio]=[equity]
通过dict.setdefault(key,default)使这段代码工作的更好:
Python代码
equities={}
for(portfolio,equity)indata:
equities.setdefault(portfolio,[]).append(
equity)
dict.setdefault()等同于“get,orset&get“或"如果没有,就设置";如果你的字典Key是复杂的计算或long类型,使用setdefault是特别有效的。
字典中的setdefault函数
(2)
在我们看到的setdefault字典方法也可以作为一个独立的语句使用:
Python代码
avs={}
for(portfolio,equity,position)indata:
navs.setdefault(portfolio,0)
navs[portfolio]+=position*prices[equity]
我们在这里忽略了字典的setdefault方法返回的默认值。
我们正利用的setdefault中的作用,仅仅只是在dict中没有key的值的时候才会设置。
创建&分割字典
如果你有两份list对象,希望通过这两个对象构建一个dict对象。
Python代码
given=[‘John’,’Eric’,’Terry’,’Michael’]
family=[‘Cleese’,’Idle’,’Gilliam’,’Palin’]
pythons=dict(zip(given,family))
>>>pprint.pprint(pythons)
{‘John’:
’Cleese’,
‘Michael’:
’Palin’,
‘Eric’:
’Idle’,
‘Terry’:
’Gilliam’}
同样,如果希望获取两份列表,也是非常简单:
Python代码
>>>pythons.keys()
[‘John’,’Michael’,’Eric’,’Terry’]
>>>pythons.values()
[‘Cleese’,’Palin’,’Idle’,’Gilliam’]
需要注意的是,上面list虽然是有序的,但是dict中的keys和values是无序的,这正是因为dict本质就是无序存储的。
索引&项
(1)
如果你需要一个列表,这里有一个可爱的方式来节省你的输入:
Python代码
>>>items=‘zeroonetwothree’.split()
>>>printitems
[‘zero’,’one’,’two’,’three’]
如果我们需要遍历这个list,而且需要index和item:
Python代码
-or-
i=0
foriteminitems:
foriinrange(len(items)):
printi,itemprinti,items[i]
i+=1
索引&项
(2):
enumerate
通过enumerate可以返回list中的(index,item)元组:
Python代码