你可能不知道的30个Python语言的特点技巧(1)


1   介绍

从我开始学习Python时我就决定维护一个经常使用的“窍门”列表。不论何时当我看到一段让我觉得“酷,这样也行!”的代码时在一个例子中、在StackOverflow、在开源码软件中,等等),我会尝试它直到理解它,然后把它添加到列表中。这篇文章是清理过列表的一部分。如果你是一个有经验的Python程序员,尽管你可能已经知道一些,但你仍能发现一些你不知道的。如果你是一个正在学习Python的C、C++或Java程序员,或者刚开始学习编程,那么你会像我一样发现它们中的很多非常有用。

 

每个窍门或语言特性只能通过实例来验证,无需过多解释。虽然我已尽力使例子清晰,但它们中的一些仍会看起来有些复杂,这取决于你的熟悉程度。所以如果看过例子后还不清楚的话,标题能够提供足够的信息让你通过Google获取详细的内容。

列表按难度排序,常用的语言特征和技巧放在前面。

1.1   分拆

  1. >>> a, b, c = 123 
  2. >>> a, b, c  
  3. (123)  
  4. >>> a, b, c = [123]  
  5. >>> a, b, c  
  6. (123)  
  7. >>> a, b, c = (2 * i + 1 for i in range(3))  
  8. >>> a, b, c  
  9. (135)  
  10. >>> a, (b, c), d = [1, (23), 4]  
  11. >>> a  
  12. 1 
  13. >>> b  
  14. 2 
  15. >>> c  
  16. 3 
  17. >>> d  
  18. 4 

1.2   交换变量分拆

  1. >>> a, b = 12 
  2. >>> a, b = b, a  
  3. >>> a, b  
  4. (21

1.3   拓展分拆 (Python 3下适用)

  1. >>> a, *b, c = [12345]  
  2. >>> a  
  3. 1 
  4. >>> b  
  5. [234]  
  6. >>> c  
  7. 5 

1.4   负索引

  1. >>> a = [012345678910]  
  2. >>> a[-1]  
  3. 10 
  4. >>> a[-3]  
  5. 8 

1.5   列表切片 (a[start:end])

  1. >>> a = [012345678910]  
  2. >>> a[2:8]  
  3. [234567

1.6   使用负索引的列表切片

  1. >>> a = [012345678910]  
  2. >>> a[-4:-2]  
  3. [78

1.7   带步进值的列表切片 (a[start:end:step])

  1. >>> a = [012345678910]  
  2. >>> a[::2]  
  3. [0246810]  
  4. >>> a[::3]  
  5. [0369]  
  6. >>> a[2:8:2]  
  7. [246

1.8   负步进值得列表切片

  1. >>> a = [012345678910]  
  2. >>> a[::-1]  
  3. [109876543210]  
  4. >>> a[::-2]  
  5. [1086420

1.9   列表切片赋值

  1. >>> a = [12345]  
  2. >>> a[2:3] = [00]  
  3. >>> a  
  4. [120045]  
  5. >>> a[1:1] = [89]  
  6. >>> a  
  7. [18920045]  
  8. >>> a[1:-1] = []  
  9. >>> a  
  10. [15

1.10   命名切片 (slice(start, end, step))

  1. >>> a = [012345]  
  2. >>> LASTTHREE = slice(-3None)  
  3. >>> LASTTHREE  
  4. slice(-3NoneNone)  
  5. >>> a[LASTTHREE]  
  6. [345

1.11   zip打包解包列表和倍数

  1. >>> a = [123]  
  2. >>> b = ['a''b''c']  
  3. >>> z = zip(a, b)  
  4. >>> z  
  5. [(1'a'), (2'b'), (3'c')]  
  6. >>> zip(*z)  
  7. [(123), ('a''b''c')] 

1.12   使用zip合并相邻的列表项

  1. >>> a = [123456]  
  2. >>> zip(*([iter(a)] * 2))  
  3. [(12), (34), (56)]  
  4.  
  5. >>> group_adjacent = lambda a, k: zip(*([iter(a)] * k))  
  6. >>> group_adjacent(a, 3)  
  7. [(123), (456)]  
  8. >>> group_adjacent(a, 2)  
  9. [(12), (34), (56)]  
  10. >>> group_adjacent(a, 1)  
  11. [(1,), (2,), (3,), (4,), (5,), (6,)]  
  12.  
  13. >>> zip(a[::2], a[1::2])  
  14. [(12), (34), (56)]  
  15.  
  16. >>> zip(a[::3], a[1::3], a[2::3])  
  17. [(123), (456)]  
  18.  
  19. >>> group_adjacent = lambda a, k: zip(*(a[i::k] for i in range(k)))  
  20. >>> group_adjacent(a, 3)  
  21. [(123), (456)]  
  22. >>> group_adjacent(a, 2)  
  23. [(12), (34), (56)]  
  24. >>> group_adjacent(a, 1)  
  25. [(1,), (2,), (3,), (4,), (5,), (6,)] 

1.13  使用zip和iterators生成滑动窗口 (n -grams) 

  1. >>> from itertools import islice  
  2. >>> def n_grams(a, n):  
  3. ...     z = (islice(a, i, Nonefor i in range(n))  
  4. ...     return zip(*z)  
  5. ...  
  6. >>> a = [123456]  
  7. >>> n_grams(a, 3)  
  8. [(123), (234), (345), (456)]  
  9. >>> n_grams(a, 2)  
  10. [(12), (23), (34), (45), (56)]  
  11. >>> n_grams(a, 4)  
  12. [(1234), (2345), (3456)] 

1.14   使用zip反转字典

  1. >>> m = {'a'1'b'2'c'3'd'4}  
  2. >>> m.items()  
  3. [('a'1), ('c'3), ('b'2), ('d'4)]  
  4. >>> zip(m.values(), m.keys())  
  5. [(1'a'), (3'c'), (2'b'), (4'd')]  
  6. >>> mi = dict(zip(m.values(), m.keys()))  
  7. >>> mi  
  8. {1'a'2'b'3'c'4'd'

1.15   摊平列表:

  1. >>> a = [[12], [34], [56]]  
  2. >>> list(itertools.chain.from_iterable(a))  
  3. [123456]  
  4.  
  5. >>> sum(a, [])  
  6. [123456]  
  7.  
  8. >>> [x for l in a for x in l]  
  9. [123456]  
  10.  
  11. >>> a = [[[12], [34]], [[56], [78]]]  
  12. >>> [x for l1 in a for l2 in l1 for x in l2]  
  13. [12345678]  
  14.  
  15. >>> a = [12, [34], [[56], [78]]]  
  16. >>> flatten = lambda x: [y for l in x for y in flatten(l)] if type(x) is list else [x]  
  17. >>> flatten(a)  
  18. [12345678

注意: 根据Python的文档,itertools.chain.from_iterable是首选。

1.16   生成器表达式

  1. >>> g = (x ** 2 for x in xrange(10))  
  2. >>> next(g)  
  3. 0 
  4. >>> next(g)  
  5. 1 
  6. >>> next(g)  
  7. 4 
  8. >>> next(g)  
  9. 9 
  10. >>> sum(x ** 3 for x in xrange(10))  
  11. 2025 
  12. >>> sum(x ** 3 for x in xrange(10if x % 3 == 1)  
  13. 408 

1.17   迭代字典

  1. >>> m = {x: x ** 2 for x in range(5)}  
  2. >>> m  
  3. {00112439416}  
  4.  
  5. >>> m = {x: 'A' + str(x) for x in range(10)}  
  6. >>> m  
  7. {0'A0'1'A1'2'A2'3'A3'4'A4'5'A5'6'A6'7'A7'8'A8'9'A9'

1.18   通过迭代字典反转字典

  1. >>> m = {'a'1'b'2'c'3'd'4}  
  2. >>> m  
  3. {'d'4'a'1'b'2'c'3}  
  4. >>> {v: k for k, v in m.items()}  
  5. {1'a'2'b'3'c'4'd'

1.19   命名序列 (collections.namedtuple)

  1. >>> Point = collections.namedtuple('Point', ['x''y'])  
  2. >>> p = Point(x=1.0, y=2.0)  
  3. >>> p  
  4. Point(x=1.0, y=2.0)  
  5. >>> p.x  
  6. 1.0 
  7. >>> p.y  
  8. 2.0 

1.20   命名列表的继承:

  1. >>> class Point(collections.namedtuple('PointBase', ['x''y'])):  
  2. ...     __slots__ = ()  
  3. ...     def __add__(self, other):  
  4. ...             return Point(x=self.x + other.x, y=self.y + other.y)  
  5. ...  
  6. >>> p = Point(x=1.0, y=2.0)  
  7. >>> q = Point(x=2.0, y=3.0)  
  8. >>> p + q  
  9. Point(x=3.0, y=5.0

1.21   集合及集合操作

  1. >>> A = {1233}  
  2. >>> A  
  3. set([123])  
  4. >>> B = {34567}  
  5. >>> B  
  6. set([34567])  
  7. >>> A | B  
  8. set([1234567])  
  9. >>> A & B  
  10. set([3])  
  11. >>> A - B  
  12. set([12])  
  13. >>> B - A  
  14. set([4567])  
  15. >>> A ^ B  
  16. set([124567])  
  17. >>> (A ^ B) == ((A - B) | (B - A))  
  18. True 

1.22   多重集及其操作 (collections.Counter)

  1. >>> A = collections.Counter([122])  
  2. >>> B = collections.Counter([223])  
  3. >>> A  
  4. Counter({2211})  
  5. >>> B  
  6. Counter({2231})  
  7. >>> A | B  
  8. Counter({221131})  
  9. >>> A & B  
  10. Counter({22})  
  11. >>> A + B  
  12. Counter({241131})  
  13. >>> A - B  
  14. Counter({11})  
  15. >>> B - A  
  16. Counter({31}) 

1.23   迭代中最常见的元素 (collections.Counter)

  1. >>> A = collections.Counter([112233334567])  
  2. >>> A  
  3. Counter({34122241516171})  
  4. >>> A.most_common(1)  
  5. [(34)]  
  6. >>> A.most_common(3)  
  7. [(34), (12), (22)] 

1.24   双端队列 (collections.deque)

  1. >>> Q = collections.deque()  
  2. >>> Q.append(1)  
  3. >>> Q.appendleft(2)  
  4. >>> Q.extend([34])  
  5. >>> Q.extendleft([56])  
  6. >>> Q  
  7. deque([652134])  
  8. >>> Q.pop()  
  9. 4 
  10. >>> Q.popleft()  
  11. 6 
  12. >>> Q  
  13. deque([5213])  
  14. >>> Q.rotate(3)  
  15. >>> Q  
  16. deque([2135])  
  17. >>> Q.rotate(-3)  
  18. >>> Q  
  19. deque([5213]) 


评论关闭