Things you may not know about Python

1. 可传递的条件表达式:

>>> a,b,c,d = 1,2,2,3
>>> if a<b==c<d:
...     print 'voila!'
...
voila!

我以前受C语言的毒害,一直写成 if (a<b) and (b==c) and (c<d),汗

2. 分开写的格式化字符串:

>>> greetings = 'Hello, %s!'
>>> print greetings%'pala'
Hello, pala!

格式符(%s)相当于参数,如同函数中,可以先设置参数,随后再传递参数。

3. 把字符串的每个单词的首字母大写:

>>> s = 'i love python!'
>>> s.title()
'I Love Python!'

这个字符串方法的名字很难想到,我总觉得capitalize()应该是这个效果,不过其实capitalize只大写整个字符串的首字符。

4. 给字典添加新的键值对,但如果已有这个键则不修改字典:

>>> d = dict(a=1,b=2)
>>> d.setdefault('b',3)
2
>>> d
{'a': 1, 'b': 2}
>>> d.setdefault('c',3)
3
>>> d
{'a': 1, 'c': 3, 'b': 2}

这样可以放心大胆的添加新的键值对,而不必担心把已有的键值对给覆盖了。

5. 序列的'+'运算符的效率问题

序列(sequence)类型包括字符串、列表(list)等。'+'运算可以连接2个序列:
>>> s1 = 'about'
>>> s2 = 'python'
>>> s1+s2
'aboutpython'
>>> l1 = ['pineapple','orange']
>>> l2 = ['strawberry']
>>> l1+l2
['pineapple', 'orange', 'strawberry']

据说,由于python底层C语言实现的不同,'+'运算不如一些等价方法效率高。于是,字符串连接推荐用格式化字符串或join()方法,list连接推荐用extend()方法。

>>> '%s%s'%(s1,s2)
'aboutpython'
>>> ''.join([s1,s2])
'aboutpython'
>>> l1.extend(l2)
>>> l1
['pineapple', 'orange', 'strawberry']

另,l1.extend(l2) 是直接修改l1, 而 l1+l2 是产生一个新的list,因此,如果不考虑效率,可以用 l1+=l2 达到和 l1.extend(l2) 同样的结果。

(未完待续)

以下文章也许和本文有点关系:

那年今天:

3条留言 跳到评论框

  1. ygc
    发表于March 8, 2009 10:55 PM | 永久链接

    python一直没能吸引我去学它。。

    [回复这条留言]

  2. szl
    发表于April 3, 2009 9:50 AM | 永久链接

    你的第一条写成 if a<b==c<d: 明显不是一个很好的编程习惯。应该按照C的方法写。这叫write clear code not smart code.

    第四条里,setdefault效率好像还没有if not k in dict: dict[k]=value 高。

    [回复这条留言]

    azalea

    回复于April 3, 2009 1:31 PM

    第一条,保留意见,我觉得a < b == c < d很clear啊。
    或者换个例子:
    >>> a = 3
    >>> if 2 < a < 4:
    ... print a
    ...
    3

    我觉得要比分开写更清楚

    第四条,我要去研究研究,据说有本书不错

    [回复这条留言]

    szl116

    回复于April 3, 2009 3:21 PM

    你这个能把留言发到我油箱啊?

    第一个 我第一眼就觉得是这个逻辑:

    (a < b) == (c < d)

    而不是你说的C的那个逻辑:if (a<b) and (b==c) and (c<d):

    因为我误以为 == 比 < 级别要高。

    你第二个例子你试试 a = 1

    setdefault那个我第一次见istvan用,后来我在自己code里试验过,有些情况下setdefault不一定快。但是我不知道具体setdefault实现的机制能否保证比if判断快。

    [回复这条留言]

    azalea

    回复于April 3, 2009 3:35 PM

    恩啊,那个 == 确实会引起误会,以后只用在同方向的比较就好了。
    >>> a = 1
    >>> if 2 < a < 4:
    ... print a
    ...
    >>>
    没啥问题啊

    我刚才说的书是这个,
    http://www.douban.com/subject/3117898/?from=mb-126202970
    里面讲了python的底层实现

    ps.我是看了istvan才知道你是谁=.=

    [回复这条留言]

    szl116

    回复于April 3, 2009 3:39 PM

    那个源码剖析确实牛。而且竟然是原创的。

    可惜买不到啊。你知道怎么从国内买书么?

    [回复这条留言]

    azalea

    回复于April 3, 2009 4:02 PM

    不知道哦 没买过
    可以找人买了 寄过来吧 =.=
    刚看了一下,当当网可以平邮到美国,运费50RMB

    那本书的在线版本:
    http://blog.csdn.net/balabalamerobert/category/168910.aspx?PageNumber=2

    [回复这条留言]

    szl116

    回复于April 3, 2009 4:18 PM

    网上那个不全吧。

    关于这个chain comparison,我总觉得用着不踏实。因为Python隐式转换。

    比如你可以
    >>> True < 5
    True

    这种chain comparison是不是只适合比较操作符呢?你是从什么地方看的这个写法?

    [回复这条留言]

    azalea

    回复于April 3, 2009 4:40 PM

    最早在python documentation里看到,刚才找不到了=.=
    wikipedia上的解释:
    http://en.wikipedia.org/wiki/Python_syntax_and_semantics#Operators

    [回复这条留言]

  3. GalaxySong
    发表于May 22, 2009 1:56 AM | 永久链接

    【据说,由于python底层C语言实现的不同,’+'运算不如一些等价方法效率高。于是,字符串连接推荐用格式化字符串或join()方法,list连接推荐用extend()方法。】
    真的吗?
    效率上究竟相差了多少?
    毕竟把字符串“相加”改成“join”也太麻烦了吧。

    [回复这条留言]

    azalea

    回复于May 22, 2009 2:12 AM

    刚才去查了一下:
    string的"+"运算是O(n^2),字符串的join()是O(n)
    详见这里:
    http://jaynes.colorado.edu/PythonIdioms.html

    [回复这条留言]

    GalaxySong

    回复于May 22, 2009 2:47 AM

    谢谢!
    不知道Python 3 有没有改进字符串“加法”的效率。
    不过,join的应用范围毕竟有限,我想,只有必要时再用吧。

    [回复这条留言]

    azalea

    回复于May 22, 2009 2:56 AM

    这个不太了解,我看到的python3比较大的改进是
    很多以前返回一个list的函数现在都返回iterator了
    比如range()函数

    如果只是2个字符串连接,用"+"运算无所谓的,不过对于很多字符串,用join()还是好的习惯了

    [回复这条留言]

发表新留言

*
*