python是一种常用的解释性语言,它相对于C\C++来说,使用起来更加方便,所以在工作和学习中,一些小工具的实现用python完成是个不之选。此处对python的优缺点就不过多介绍了,有兴趣的同学可以了解下:http://www.cnblogs.com/rourou1/p/6039108.html
《Effective python》第一章主要介绍了python代码中的一些规范,以及如何是代码看起来更加清晰,简介。此文将第一章所涉及到的知识点进行了整理,在此之前,先讲讲我在python初期遇到的一些坑吧:
Error1:import urllib.parse失败
ImportError: No module named parse
出错误原因:是因为我使用的Python版本是2.7,根据Python 2.x urlparse模块文档,urlparse模块在Python 3中重命名为urllib.parse所以模块在Python 2.7下你应该使用urlparse
Error2:在代码中出现中文,导致运行出错
SyntaxError: Non-ASCII character ‘\xca’ in file **/study.py on line 34, but no encoding declared;
原因:Python默认是以ASCII作为编码方式的,如果在自己的Python源码中包含了中文(或者其他的语言),此时即使你把自己编写的Python源文件以UTF-8格式保存了;但实际上,这依然是不行的。
解决方法:在源码的第一行添加以下语句:
# -*- coding: UTF-8 -*- 或者 #coding=utf-8
(注:此语句一定要添加在源代码的第一行,在python的使用中,编码方式是需要格外关心的,否则很容易因为编码原因出错)
说完这两个小错误之后,下面开始知识点show:
知识点1:parse_qs()
parse_qs()用法:解析字符串并且返回一个字典或列表,参数keep_blank_values为是否保留value值为空的元素。
>>>my_values = parse_qs('red=5&blue=0&green=', keep_blank_values=True);
结果:{'blue': ['0'], 'green': [''], 'red': ['5']}
>>>my_values = parse_qs('red=5&blue=0&green=', keep_blank_values=FALSE);
结果{'blue': ['0'], 'red': ['5']}
扩展:urlparse模块
url地址主要由6个部件组成,分别为:网络协议(scheme)、服务器位置(netloc)、网页文件在服务器上存放位置(path)、可选参数(parameters)、连接符(&)连接键值对(query)、拆分文档中的特殊猫(fragment)。urlparse模块主要是把url拆分为上面的6部分,并以元组的形式返回。同时该模块也提供了一些可以把拆分后的部分再组成一个url的函数。主要有函数有urlparse、urlunparse、urlsplit、urlunsplit、urljoin等。
1.urlparse:urlparse.urlparse(urlstring[, scheme[, allow_fragments]])
功能: 将urlstring解析成6个部分,它从urlstring中取得URL,并返回元组 (scheme, netloc, path, parameters, query, fragment) 。
eg: import urlparse
url=urlparse.urlparse('http://www.cnblogs.com/rourou1/p/6039108.html')
print url
>>>
ParseResult(scheme='http', netloc='www.cnblogs.com', path='/rourou1/p/6039108.html', params='', query='', fragment='')
2.urlunparse:urlparse.urlunparse(parts)
功能:从一个元组构建一个url,元组类似urlparse返回值,它接收元组后,会重新组成一个具有正确格式的URL,以便供Python的其他HTML解析模块使用。
eg: import urlparse
u=urlparse.urlunparse(url) #将上面得到的元组url传入
print u
>>>
http://www.cnblogs.com/rourou1/p/6039108.html
3.urlsplit:urlparse.urlsplit(urlstring[, scheme[, allow_fragments]])
功能:主要是分析urlstring,返回一个包含5个字符串项目的元组:协议、位置、路径、查询、片段。allowf_ragments为False时,该元组的组后一个项目总是空,不管urlstring有没有片段,省略项目的也是空。urlsplit()和urlparse()差不多。不过它不切分URL的参数。适用于遵循RFC2396的URL,每个路径段都支持参数。 这样返回的元组就只有5个元素。
eg: import urlparse
url_split=urlparse.urlsplit('http://www.cnblogs.com/rourou1/p/6039108.html')
print url_split
>>>
SplitResult(scheme='http', netloc='www.cnblogs.com', path='/rourou1/p/6039108.html', query='', fragment='')
4.urlunsplit:urlparse.urlunsplit(parts)
功能:urlunsplit使用urlsplit()返回的值组合成一个url
eg: import urlparse
u_unsplit = urlparse.urlunsplit(url_split)
print u_unsplit
>>>
http://www.cnblogs.com/rourou1/p/6039108.html
5.urljoin:urlparse.urljoin(base, url[, allow_fragments)
功能:urljoin主要是拼接URL,它以base作为其基地址,然后与url中的相对地址相结合组成一个绝对URL地址。函数urljoin在通过为URL基地址附加新的文件名的方式来处理同一位置处的若干文件的时候格外有用。需要注意的是,如果基地址并非以字符结尾的话,那么URL基地址最右边部分就会被这个相对路径所替换。 如果希望在该路径中保留末端目录, 应确保URL基地址以字符 ‘/’ 结尾。
eg: import urlparse
print urlparse.urljoin('http://www.cnblogs.com/rourou1/p/6039108.html', '4039108.html')
>>>
http://www.cnblogs.com/rourou1/p/4039108.html
print urlparse.urljoin('http://www.cnblogs.com/rourou1/p/6039108.html/', '4039108.html')
>>>
http://www.cnblogs.com/rourou1/p/6039108.html/4039108.html
知识点2:列表推导
列表推导时python提供的一种精练的写法,他可以根据一份列表来制作另一份列表,它时由一个表达式加一个for循环语句构成,执行结束后返回一个列表。
1、获取平方列表
eg: a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
squares = [x**2 for x in a]
print squares
>>>
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
同样,它也可以通过添加if语句来实现某些元素的过滤,如下,只计算能被2整除的元素的平方值:
eg: a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
squares = [x**2 for x in a if x%2 == 0]
print squares
>>>
[4, 16, 36, 64, 100]
它是以列表的形式返回每一个元素执行[后面的表达式之后的结果,整个表达式必用看起来很清晰、简洁 。
2、除去字符串中的指定字母
eg: my_str = 'hello, i am a student' #原有的字符串
exclude = 'aeiou' #需要去掉的字符
dest_str = ''.join([l for l in my_str if not l in exclude]) #''.join()是将得到的新列表中的元素添加到字符串中,为了能获得一个满足要求的字符串
print dest_str
>>>
hll, m stdnt
3、多重循环
列表推导也可以支持多重循环,比如下面这个例子,将一个二维列表简化成一个一维列表:
eg: matrix = [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]
flat = [i for row in matrix for i in row]
print flat
>>>
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
它是使用了两个循环去遍历整个矩阵,第一个是按行迭代,第二个是队改行中的每个元素进行迭代。
再进一步,如果我们需要将二维列表简化为一维列表的同时将每个元素求平方,那表达式将变为:
eg: matrix = [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]
flat = [i**2 for row in matrix for i in row]
print flat
>>>
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121]
4、多个if条件
列表推导式不仅支持多个循环,同时也支持多条if语句。比如,需要从一个列表中找出大于4的偶数,则下面两种表达式结果相同:
eg:
方法1:
array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
first_type = [x for x in array if x > 4 if x%2 == 0]
print first_type
>>>
[6, 8, 10]
方法2:
array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
first_type = [x for x in array if x > 4 and x%2 == 0]
print first_type
>>>
[6, 8, 10]
由上面两个结果可以看出,同一级个循环级别的if语句之间默认以and形式连接。
5、多个for循环与多个if条件
列表推导中每级for循环后均可添加条件,例如,从二维列表中找出元素能被3整除,且所在行所有元素和大于10的单元格,可以通过下面表达式实现:
eg: matrix = [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]
flat = [[x for x in row if x%3 == 0] for row in matrix if sum(row) > 10]
print flat
>>>
[[6], [9]]
这样,多层循环并且每个表达式都附加由判断条件,使别人阅读代码时不已理解,所以应该尽量避免列表推导式超过两个表达式的情况。