这篇博客其实就是这个集合整理后一部分的公开亮相。如果你已经是个python大牛,那么基本上你应该知道这里面的大多数用法了,但我想你应该也能发现一些你不知道的新技巧。而如果你之前是一个c,c++,java的程序员,同时在学习python,或者干脆就是一个刚刚学习编程的新手,那么你应该会看到很多特别有用能让你感到惊奇的实用技巧,就像我当初一样。
每一个技巧和语言用法都会在一个个实例中展示给大家,也不需要有其他的说明。我已经尽力把每个例子弄的通俗易懂,但是因为读者对python的熟悉程度不同,仍然可能难免有一些晦涩的地方。所以如果这些例子本身无法让你读懂,至少这个例子的标题在你后面去google搜索的时候会帮到你。
整个集合大概是按照难易程度排序,简单常见的在前面,比较少见的在最后。
1.1 拆箱
代码如下:
>>> 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]>>> a1>>> b2>>> c3>>> d4
1.2 拆箱变量交换
代码如下:
>>> a, b = 1, 2>>> a, b = b, a>>> a, b(2, 1)
1.3 扩展拆箱(只兼容python3)
代码如下:
>>> a, *b, c = [1, 2, 3, 4, 5]>>> a1>>> b[2, 3, 4]>>> c5
1.4 负数索引
代码如下:
>>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]>>> a[-1]10>>> a[-3]8
1.5 切割列表
代码如下:
>>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]>>> a[2:8][2, 3, 4, 5, 6, 7]
1.6 负数索引切割列表
代码如下:
>>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]>>> a[-4:-2][7, 8]
1.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 负数步长切割列表
代码如下:
>>> 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 列表切割赋值
代码如下:
>>> 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 命名列表切割方式
代码如下:
>>> a = [0, 1, 2, 3, 4, 5]>>> lastthree = slice(-3, none)>>> lastthreeslice(-3, none, none)>>> a[lastthree][3, 4, 5]
1.11 列表以及迭代器的压缩和解压缩
代码如下:
>>> 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 列表相邻元素压缩器
代码如下:
>>> 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 在列表中用压缩器和迭代器滑动取值窗口
代码如下:
>>> 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 用压缩器反转字典
代码如下:
>>> 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 列表展开
代码如下:
>>> 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 生成器表达式
代码如下:
>>> 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 字典推导
代码如下:
>>> 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 用字典推导反转字典
代码如下:
>>> 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 命名元组
代码如下:
>>> point = collections.namedtuple(‘point’, [‘x’, ‘y’])>>> p = point(x=1.0, y=2.0)>>> ppoint(x=1.0, y=2.0)>>> p.x1.0>>> p.y
2.01.20 继承命名元组
代码如下:
>>> 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 + qpoint(x=3.0, y=5.0)
1.21 操作集合
代码如下:
>>> a = {1, 2, 3, 3}>>> aset([1, 2, 3])>>> b = {3, 4, 5, 6, 7}>>> bset([3, 4, 5, 6, 7])>>> a | bset([1, 2, 3, 4, 5, 6, 7])>>> a & bset([3])>>> a – bset([1, 2])>>> b – aset([4, 5, 6, 7])>>> a ^ bset([1, 2, 4, 5, 6, 7])>>> (a ^ b) == ((a – b) | (b – a))true
1.22 操作多重集合
代码如下:
>>> a = collections.counter([1, 2, 2])>>> b = collections.counter([2, 2, 3])>>> acounter({2: 2, 1: 1})>>> bcounter({2: 2, 3: 1})>>> a | bcounter({2: 2, 1: 1, 3: 1})>>> a & bcounter({2: 2})>>> a + bcounter({2: 4, 1: 1, 3: 1})>>> a – bcounter({1: 1})>>> b – acounter({3: 1})
1.23 统计在可迭代器中最常出现的元素
代码如下:
>>> a = collections.counter([1, 1, 2, 2, 3, 3, 3, 3, 4, 5, 6, 7])>>> acounter({3: 4, 1: 2, 2: 2, 4: 1, 5: 1, 6: 1, 7: 1})>>> a.most_common(1)[(3, 4)]>>> a.most_common(3)[(3, 4), (1, 2), (2, 2)]
1.24 两端都可操作的队列
代码如下:
>>> q = collections.deque()>>> q.append(1)>>> q.appendleft(2)>>> q.extend([3, 4])>>> q.extendleft([5, 6])>>> qdeque([6, 5, 2, 1, 3, 4])>>> q.pop()4>>> q.popleft()6>>> qdeque([5, 2, 1, 3])>>> q.rotate(3)>>> qdeque([2, 1, 3, 5])>>> q.rotate(-3)>>> qdeque([5, 2, 1, 3])
1.25 有最大长度的双端队列
代码如下:
>>> last_three = collections.deque(maxlen=3)>>> for i in xrange(10):… last_three.append(i)… print ‘, ‘.join(str(x) for x in last_three)…00, 10, 1, 21, 2, 32, 3, 43, 4, 54, 5, 65, 6, 76, 7, 87, 8, 9
1.26 可排序词典
代码如下:
>>> m = dict((str(x), x) for x in range(10))>>> print ‘, ‘.join(m.keys())1, 0, 3, 2, 5, 4, 7, 6, 9, 8>>> m = collections.ordereddict((str(x), x) for x in range(10))>>> print ‘, ‘.join(m.keys())0, 1, 2, 3, 4, 5, 6, 7, 8, 9>>> m = collections.ordereddict((str(x), x) for x in range(10, 0, -1))>>> print ‘, ‘.join(m.keys())10, 9, 8, 7, 6, 5, 4, 3, 2, 1
1.27 默认词典
代码如下:
>>> m = dict()>>> m[‘a’]traceback (most recent call last): file “”, line 1, in keyerror: ‘a’>>>>>> m = collections.defaultdict(int)>>> m[‘a’]0>>> m[‘b’]0>>> m = collections.defaultdict(str)>>> m[‘a’]”>>> m[‘b’] += ‘a’>>> m[‘b’]’a’>>> m = collections.defaultdict(lambda: ‘[default value]’)>>> m[‘a’]'[default value]’>>> m[‘b’]'[default value]’
1.28 默认字典的简单树状表达
代码如下:
>>> import json>>> tree = lambda: collections.defaultdict(tree)>>> root = tree()>>> root[‘menu’][‘id’] = ‘file’>>> root[‘menu’][‘value’] = ‘file’>>> root[‘menu’][‘menuitems’][‘new’][‘value’] = ‘new’>>> root[‘menu’][‘menuitems’][‘new’][‘onclick’] = ‘new();’>>> root[‘menu’][‘menuitems’][‘open’][‘value’] = ‘open’>>> root[‘menu’][‘menuitems’][‘open’][‘onclick’] = ‘open();’>>> root[‘menu’][‘menuitems’][‘close’][‘value’] = ‘close’>>> root[‘menu’][‘menuitems’][‘close’][‘onclick’] = ‘close();’>>> print json.dumps(root, sort_keys=true, indent=4, separators=(‘,’, ‘: ‘)){ “menu”: { “id”: “file”, “menuitems”: { “close”: { “onclick”: “close();”, “value”: “close” }, “new”: { “onclick”: “new();”, “value”: “new” }, “open”: { “onclick”: “open();”, “value”: “open” } }, “value”: “file” }}
1.29 对象到唯一计数的映射
代码如下:
>>> import itertools, collections>>> value_to_numeric_map = collections.defaultdict(itertools.count().next)>>> value_to_numeric_map[‘a’]0>>> value_to_numeric_map[‘b’]1>>> value_to_numeric_map[‘c’]2>>> value_to_numeric_map[‘a’]0>>> value_to_numeric_map[‘b’]1
1.30 最大和最小的几个列表元素
代码如下:
>>> a = [random.randint(0, 100) for __ in xrange(100)]>>> heapq.nsmallest(5, a)[3, 3, 5, 6, 8]>>> heapq.nlargest(5, a)[100, 100, 99, 98, 98]
1.31 两个列表的笛卡尔积
代码如下:
>>> for p in itertools.product([1, 2, 3], [4, 5]):(1, 4)(1, 5)(2, 4)(2, 5)(3, 4)(3, 5)>>> for p in itertools.product([0, 1], repeat=4):… print ”.join(str(x) for x in p)…0000000100100011010001010110011110001001101010111100110111101111
1.32 列表组合和列表元素替代组合
代码如下:
>>> for c in itertools.combinations([1, 2, 3, 4, 5], 3):… print ”.join(str(x) for x in c)…123124125134135145234235245345>>> for c in itertools.combinations_with_replacement([1, 2, 3], 2):… print ”.join(str(x) for x in c)…111213222333
1.33 列表元素排列组合
代码如下:
>>> for p in itertools.permutations([1, 2, 3, 4]):… print ”.join(str(x) for x in p)…123412431324134214231432213421432314234124132431312431423214324134123421412341324213423143124321
1.34 可链接迭代器
代码如下:
>>> a = [1, 2, 3, 4]>>> for p in itertools.chain(itertools.combinations(a, 2), itertools.combinations(a, 3)):… print p…(1, 2)(1, 3)(1, 4)(2, 3)(2, 4)(3, 4)(1, 2, 3)(1, 2, 4)(1, 3, 4)(2, 3, 4)>>> for subset in itertools.chain.from_iterable(itertools.combinations(a, n) for n in range(len(a) + 1))… print subset…()(1,)(2,)(3,)(4,)(1, 2)(1, 3)(1, 4)(2, 3)(2, 4)(3, 4)(1, 2, 3)(1, 2, 4)(1, 3, 4)(2, 3, 4)(1, 2, 3, 4)
1.35 根据文件指定列类聚
代码如下:
>>> import itertools>>> with open(‘contactlenses.csv’, ‘r’) as infile:… data = [line.strip().split(‘,’) for line in infile]…>>> data = data[1:]>>> def print_data(rows):… print ‘\n’.join(‘\t’.join(‘{: