从我开始学习python的时候,我就开始自己总结一个python小技巧的集合。后来当我什么时候在Stack Overflow 或者在某个开源软件里看到一段很酷代码的时候,我就很惊讶:原来还能这么做!,当时我会努力的自己尝试一下这段代码,直到我懂了它的整体思路以后,我就把这段代码加到我的集合里。这篇博客其实就是这个集合整理后一部分的公开亮相。如果你已经是个python大牛,那么基本上你应该知道这里面的大多数用法了,但我想你应该也能发现一些你不知道的新技巧。而如果你之前是一个c,c++,java的程序员,同时在学习python,或者干脆就是一个刚刚学习编程的新手,那么你应该会看到很多特别有用能让你感到惊奇的实用技巧,就像我当初一样。 每一个技巧和语言用法都会在一个个实例中展示给大家,也不需要有其他的说明。我已经尽力把每个例子弄的通俗易懂,但是因为读者对python的熟悉程度不同,仍然可能难免有一些晦涩的地方。所以如果这些例子本身无法让你读懂,至少这个例子的标题在你后面去google搜索的时候会帮到你。 整个集合大概是按照难易程度排序,简单常见的在前面,比较少见的在最后。 1.1 拆箱 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | >>> a, b, c = 1 , 2 , 3
>>> a, b, c
( 1 , 2 , 3 )
>>> a, b, c = [ 1 , 2 , 3 ]
>>> a, b, c
( 1 , 2 , 3 )
>>> a, b, c = ( 2 * i + 1 for i in range ( 3 ))
>>> a, b, c
( 1 , 3 , 5 )
>>> a, (b, c), d = [ 1 , ( 2 , 3 ), 4 ]
>>> a
1
>>> b
2
>>> c
3
>>> d
4
|
1.2 拆箱变量交换 1 2 3 4 | >>> a, b = 1 , 2
>>> a, b = b, a
>>> a, b
( 2 , 1 )
|
1.3 扩展拆箱(只兼容python3) 1 2 3 4 5 6 7 | >>> a, * b, c = [ 1 , 2 , 3 , 4 , 5 ]
>>> a
1
>>> b
[ 2 , 3 , 4 ]
>>> c
5
|
1.4 负数索引 1 2 3 4 5 | >>> a = [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ]
>>> a[ - 1 ]
10
>>> a[ - 3 ]
8
|
1.5 切割列表 1 2 3 | >>> a = [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ]
>>> a[ 2 : 8 ]
[ 2 , 3 , 4 , 5 , 6 , 7 ]
|
1.6 负数索引切割列表 1 2 3 | >>> a = [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ]
>>> a[ - 4 : - 2 ]
[ 7 , 8 ]
|
1.7指定步长切割列表 1 2 3 4 5 6 7 | >>> a = [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ]
>>> a[:: 2 ]
[ 0 , 2 , 4 , 6 , 8 , 10 ]
>>> a[:: 3 ]
[ 0 , 3 , 6 , 9 ]
>>> a[ 2 : 8 : 2 ]
[ 2 , 4 , 6 ]
|
1.8 负数步长切割列表 1 2 3 4 5 | >>> a = [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ]
>>> a[:: - 1 ]
[ 10 , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 , 0 ]
>>> a[:: - 2 ]
[ 10 , 8 , 6 , 4 , 2 , 0 ]
|
1.9 列表切割赋值 1 2 3 4 5 6 7 8 9 10 | >>> a = [ 1 , 2 , 3 , 4 , 5 ]
>>> a[ 2 : 3 ] = [ 0 , 0 ]
>>> a
[ 1 , 2 , 0 , 0 , 4 , 5 ]
>>> a[ 1 : 1 ] = [ 8 , 9 ]
>>> a
[ 1 , 8 , 9 , 2 , 0 , 0 , 4 , 5 ]
>>> a[ 1 : - 1 ] = []
>>> a
[ 1 , 5 ]
|
1.10 命名列表切割方式 1 2 3 4 5 6 | >>> a = [ 0 , 1 , 2 , 3 , 4 , 5 ]
>>> LASTTHREE = slice ( - 3 , None )
>>> LASTTHREE
slice ( - 3 , None , None )
>>> a[LASTTHREE]
[ 3 , 4 , 5 ]
|
1.11 列表以及迭代器的压缩和解压缩 1 2 3 4 5 6 7 | >>> a = [ 1 , 2 , 3 ]
>>> b = [ 'a' , 'b' , 'c' ]
>>> z = zip (a, b)
>>> z
[( 1 , 'a' ), ( 2 , 'b' ), ( 3 , 'c' )]
>>> zip ( * z)
[( 1 , 2 , 3 ), ( 'a' , 'b' , 'c' )]
|
1.12 列表相邻元素压缩器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | >>> a = [ 1 , 2 , 3 , 4 , 5 , 6 ]
>>> zip ( * ([ iter (a)] * 2 ))
[( 1 , 2 ), ( 3 , 4 ), ( 5 , 6 )]
>>> group_adjacent = lambda a, k: zip ( * ([ iter (a)] * k))
>>> group_adjacent(a, 3 )
[( 1 , 2 , 3 ), ( 4 , 5 , 6 )]
>>> group_adjacent(a, 2 )
[( 1 , 2 ), ( 3 , 4 ), ( 5 , 6 )]
>>> group_adjacent(a, 1 )
[( 1 ,), ( 2 ,), ( 3 ,), ( 4 ,), ( 5 ,), ( 6 ,)]
>>> zip (a[:: 2 ], a[ 1 :: 2 ])
[( 1 , 2 ), ( 3 , 4 ), ( 5 , 6 )]
>>> zip (a[:: 3 ], a[ 1 :: 3 ], a[ 2 :: 3 ])
[( 1 , 2 , 3 ), ( 4 , 5 , 6 )]
>>> group_adjacent = lambda a, k: zip ( * (a[i::k] for i in range (k)))
>>> group_adjacent(a, 3 )
[( 1 , 2 , 3 ), ( 4 , 5 , 6 )]
>>> group_adjacent(a, 2 )
[( 1 , 2 ), ( 3 , 4 ), ( 5 , 6 )]
>>> group_adjacent(a, 1 )
[( 1 ,), ( 2 ,), ( 3 ,), ( 4 ,), ( 5 ,), ( 6 ,)]
|
1.13 在列表中用压缩器和迭代器滑动取值窗口 1 2 3 4 5 6 7 8 9 10 11 | >>> def n_grams(a, n):
... z = [ iter (a[i:]) for i in range (n)]
... return zip ( * z)
...
>>> a = [ 1 , 2 , 3 , 4 , 5 , 6 ]
>>> n_grams(a, 3 )
[( 1 , 2 , 3 ), ( 2 , 3 , 4 ), ( 3 , 4 , 5 ), ( 4 , 5 , 6 )]
>>> n_grams(a, 2 )
[( 1 , 2 ), ( 2 , 3 ), ( 3 , 4 ), ( 4 , 5 ), ( 5 , 6 )]
>>> n_grams(a, 4 )
[( 1 , 2 , 3 , 4 ), ( 2 , 3 , 4 , 5 ), ( 3 , 4 , 5 , 6 )]
|
1.14 用压缩器反转字典 1 2 3 4 5 6 7 8 | >>> m = { 'a' : 1 , 'b' : 2 , 'c' : 3 , 'd' : 4 }
>>> m.items()
[( 'a' , 1 ), ( 'c' , 3 ), ( 'b' , 2 ), ( 'd' , 4 )]
>>> zip (m.values(), m.keys())
[( 1 , 'a' ), ( 3 , 'c' ), ( 2 , 'b' ), ( 4 , 'd' )]
>>> mi = dict ( zip (m.values(), m.keys()))
>>> mi
{ 1 : 'a' , 2 : 'b' , 3 : 'c' , 4 : 'd' }
|
1.15 列表展开 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | >>> a = [[ 1 , 2 ], [ 3 , 4 ], [ 5 , 6 ]]
>>> list (itertools.chain.from_iterable(a))
[ 1 , 2 , 3 , 4 , 5 , 6 ]
>>> sum (a, [])
[ 1 , 2 , 3 , 4 , 5 , 6 ]
>>> [x for l in a for x in l]
[ 1 , 2 , 3 , 4 , 5 , 6 ]
>>> a = [[[ 1 , 2 ], [ 3 , 4 ]], [[ 5 , 6 ], [ 7 , 8 ]]]
>>> [x for l1 in a for l2 in l1 for x in l2]
[ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ]
>>> a = [ 1 , 2 , [ 3 , 4 ], [[ 5 , 6 ], [ 7 , 8 ]]]
>>> flatten = lambda x: [y for l in x for y in flatten(l)] if type (x) is list else [x]
>>> flatten(a)
[ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ]
|
1.16 生成器表达式 1 2 3 4 5 6 7 8 9 10 11 12 13 | >>> g = (x * * 2 for x in xrange ( 10 ))
>>> next (g)
0
>>> next (g)
1
>>> next (g)
4
>>> next (g)
9
>>> sum (x * * 3 for x in xrange ( 10 ))
2025
>>> sum (x * * 3 for x in xrange ( 10 ) if x % 3 = = 1 )
408
|
1.17 字典推导 1 2 3 4 5 6 7 | >>> m = {x: x * * 2 for x in range ( 5 )}
>>> m
{ 0 : 0 , 1 : 1 , 2 : 4 , 3 : 9 , 4 : 16 }
>>> m = {x: 'A' + str (x) for x in range ( 10 )}
>>> m
{ 0 : 'A0' , 1 : 'A1' , 2 : 'A2' , 3 : 'A3' , 4 : 'A4' , 5 : 'A5' , 6 : 'A6' , 7 : 'A7' , 8 : 'A8' , 9 : 'A9' }
|
1.18 用字典推导反转字典 1 2 3 4 5 | >>> m = { 'a' : 1 , 'b' : 2 , 'c' : 3 , 'd' : 4 }
>>> m
{ 'd' : 4 , 'a' : 1 , 'b' : 2 , 'c' : 3 }
>>> {v: k for k, v in m.items()}
{ 1 : 'a' , 2 : 'b' , 3 : 'c' , 4 : 'd' }
|
1.19 命名元组 1 2 3 4 5 6 7 8 | >>> Point = collections.namedtuple( 'Point' , [ 'x' , 'y' ])
>>> p = Point(x = 1.0 , y = 2.0 )
>>> p
Point(x = 1.0 , y = 2.0 )
>>> p.x
1.0
>>> p.y
2.0
|
1.20 继承命名元组 1 2 3 4 5 6 7 8 9 | >>> class Point(collections.namedtuple( 'PointBase' , [ 'x' , 'y' ])):
... __slots__ = ()
... def __add__( self , other):
... return Point(x = self .x + other.x, y = self .y + other.y)
...
>>> p = Point(x = 1.0 , y = 2.0 )
>>> q = Point(x = 2.0 , y = 3.0 )
>>> p + q
Point(x = 3.0 , y = 5.0 )
|
|