让你瞬间萌比的35个python小技巧
今天在看python算法的时候,看到一篇关于python的小技巧。瞬间萌比了,原来python也可以这样玩,太神奇了。萌比的是原来这么简单的东西自己都不知道,虽然会写。废话不多说了,开始上菜。
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] >>> a 1 >>> b 2 >>> c 3 >>> d 4
2、拆箱变量交换
>>> a,b,c = 1,2,3 >>> a,b,c = b,c,a >>> a,b,c (2, 3, 1)
3、扩展拆箱(只兼容python3)
>>> a, *b, c = [1, 2, 3, 4, 5] >>> a 1 >>> b [2, 3, 4] >>> c 5
4、负数索引
>>> a = [1,2,3,4,5,6,7,8,9,0] >>> a[-1] 0 >>> a[-3] 8
5、切割列表
>>> a = [1,2,3,4,5,6,7,8,9,0] >>> a[2:6] [3, 4, 5, 6]
6、负数索引切割列表
>>> a = [1,2,3,4,5,6,7,8,9,] >>> a[-4:-3] [6] >>> a[-4:-7] [] >>> a[-7:-4] [3, 4, 5]
7、指定不长切割列表
>>> a=[1,2,3,4,5,6,7,8,9,0] >>> a[::3] [1, 4, 7, 0] >>> a[::2] [1, 3, 5, 7, 9] >>> a[2:8:2] [3, 5, 7] >>> a[:2:8] [1]
8、负数步长切割列表
>>> a=[1,2,3,4,5,6,7,8,9,10,11,12,13,14] >>> a[::-3] [14, 11, 8, 5, 2] >>> a[::-5] [14, 9, 4] >>> a[-2:-3:-4] [13]
9、列表切割赋值
>>> a=[1,2,3,4,5] >>> a[2:3] [3] >>> a[2:3]=[0,0] >>> a [1, 2, 0, 0, 4, 5] >>> a[1:1] [] >>> a[1:1]=[8,9] >>> a [1, 8, 9, 2, 0, 0, 4, 5] >>> a[1:-1] [8, 9, 2, 0, 0, 4] >>> a[1:-1]=[] >>> a [1, 5]
10、命名列表切割方式
>>> a=[1,2,3,4,5] >>> LASTTHREE = slice(-3,None) >>> LASTTHREE slice(-3, None, None) >>> a[LASTTHREE] [3, 4, 5]
11、列表以及迭代器的压缩和解压
>>> a=[1,2,3,4,5] >>> b=['a', 'b', 'c'] >>> z=zip(a,b) >>> z [(1, 'a'), (2, 'b'), (3, 'c')] >>> zip(*z) [(1, 2, 3), ('a', 'b', 'c')]
12、列表相邻元素压缩器
>>> a=[1,2,3,4,5] >>> zip(*([iter(a)] * 2)) [(1, 2), (3, 4)] >>> 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,)]
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,7,8,9] >>> n_grams(a,3) [(1, 2, 3), (2, 3, 4), (3, 4, 5), (4, 5, 6), (5, 6, 7), (6, 7, 8), (7, 8, 9)] >>> n_grams(a,2) [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9)] >>> n_grams(a,4) [(1, 2, 3, 4), (2, 3, 4, 5), (3, 4, 5, 6), (4, 5, 6, 7), (5, 6, 7, 8), (6, 7, 8, 9)]
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'}
15、列表展开
>>> import itertools >>> 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]
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
17、字典推导
>>> m = {x: x ** 2 for x in range(5)} >>> m {0: 0, 1: 1, 2: 4, 3: 9, 4: 16} >>> m = {x: 'B' + str(x) for x in range(10)} >>> m {0: 'B0', 1: 'B1', 2: 'B2', 3: 'B3', 4: 'B4', 5: 'B5', 6: 'B6', 7: 'B7', 8: 'B8', 9: 'B9'}
18、用字典推导反转字典
>>> m={'a':1,'b':2,'c':3,'d':4} >>> m {'a': 1, 'c': 3, 'b': 2, 'd': 4} >>> {v:k for k,v in m.items()} {1: 'a', 2: 'b', 3: 'c', 4: 'd'}
19、命名元组
>>> import collections >>> point = collections.namedtuple('point', ['x', 'y']) >>> p = point(x=1.0, y=2.0) >>> p.x 1.0 >>> p.y 2.0
20、继承命名元组
>>> import collections >>> 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 PointBase(x=3.0, y=5.0)
21、操作集合
>>> A = {1, 2, 3, 4} >>> A set([1, 2, 3, 4]) >>> B = {3, 4, 5, 6, 7} >>> B set([3, 4, 5, 6, 7]) >>> A | B set([1, 2, 3, 4, 5, 6, 7]) >>> A & B set([3, 4]) >>> A - B set([1, 2]) >>> B - A set([5, 6, 7]) >>> A ^ B set([1, 2, 5, 6, 7]) >>> (A ^ B) == ((A - B) | (B - A)) True
22、操作多重集合
>>> A = collections.Counter([1, 2, 2]) >>> B = collections.Counter([2, 2, 3]) >>> A Counter({2: 2, 1: 1}) >>> B Counter({2: 2, 3: 1}) >>> A | B Counter({2: 2, 1: 1, 3: 1}) >>> A & B Counter({2: 2}) >>> A + B Counter({2: 4, 1: 1, 3: 1}) >>> A - B Counter({1: 1}) >>> B - A Counter({3: 1})
23、统计在可迭代器中最常出现的元素
>>> A = collections.Counter([1, 1, 2, 2, 3, 3, 3, 3, 4, 5, 6, 7]) >>> A Counter({3: 4, 1: 2, 2: 2, 4: 1, 5: 1, 6: 1, 7: 1}) >>> A.most_common(1) [(3, 4)] >>> A.most_common(2) [(3, 4), (1, 2)] >>> A.most_common(3) [(3, 4), (1, 2), (2, 2)]
24、两端都可操作的队列
>>> Q = collections.deque() >>> Q.append(1) >>> Q.appendleft(2) >>> Q.extend([3, 4]) >>> Q.extendleft([5, 6]) >>> Q deque([6, 5, 2, 1, 3, 4]) >>> Q.pop() 4 >>> Q.popleft() 6 >>> Q deque([5, 2, 1, 3]) >>> Q.rotate(3) >>> Q deque([2, 1, 3, 5]) >>> Q.rotate(-3) >>> Q deque([5, 2, 1, 3])
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) ... 0 0, 1 0, 1, 2 1, 2, 3 2, 3, 4 3, 4, 5 4, 5, 6 5, 6, 7 6, 7, 8 7, 8, 9
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
27、默认词典
>>> m = dict() >>> m['a'] Traceback (most recent call last): File "<stdin>", line 1, in <module> 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]'
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" } }
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
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]
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) ... 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
32、列表组合和列表元素替代组合
>>> for c in itertools.combinations([1, 2, 3, 4, 5], 3): ... print ''.join(str(x) for x in c) ... 123 124 125 134 135 145 234 235 245 345 >>> for c in itertools.combinations_with_replacement([1, 2, 3], 2): ... print ''.join(str(x) for x in c) ... 11 12 13 22 23 33
33、列表元素排列组合
>>> for p in itertools.permutations([1, 2, 3, 4]): ... print ''.join(str(x) for x in p) ... 1234 1243 1324 1342 1423 1432 2134 2143 2314 2341 2413 2431 3124 3142 3214 3241 3412 3421 4123 4132 4213 4231 4312 4321
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)
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('{: <16}'.format(s) for s in row) for row in rows) ... >>> print_data(data) young myope no reduced none young myope no normal soft young myope yes reduced none young myope yes normal hard young hypermetrope no reduced none young hypermetrope no normal soft young hypermetrope yes reduced none young hypermetrope yes normal hard pre-presbyopic myope no reduced none pre-presbyopic myope no normal soft pre-presbyopic myope yes reduced none pre-presbyopic myope yes normal hard pre-presbyopic hypermetrope no reduced none pre-presbyopic hypermetrope no normal soft pre-presbyopic hypermetrope yes reduced none pre-presbyopic hypermetrope yes normal none presbyopic myope no reduced none presbyopic myope no normal none presbyopic myope yes reduced none presbyopic myope yes normal hard presbyopic hypermetrope no reduced none presbyopic hypermetrope no normal soft presbyopic hypermetrope yes reduced none presbyopic hypermetrope yes normal none >>> data.sort(key=lambda r: r[-1]) >>> for value, group in itertools.groupby(data, lambda r: r[-1]): ... print '-----------' ... print 'Group: ' + value ... print_data(group) ... ----------- Group: hard young myope yes normal hard young hypermetrope yes normal hard pre-presbyopic myope yes normal hard presbyopic myope yes normal hard ----------- Group: none young myope no reduced none young myope yes reduced none young hypermetrope no reduced none young hypermetrope yes reduced none pre-presbyopic myope no reduced none pre-presbyopic myope yes reduced none pre-presbyopic hypermetrope no reduced none pre-presbyopic hypermetrope yes reduced none pre-presbyopic hypermetrope yes normal none presbyopic myope no reduced none presbyopic myope no normal none presbyopic myope yes reduced none presbyopic hypermetrope no reduced none presbyopic hypermetrope yes reduced none presbyopic hypermetrope yes normal none ----------- Group: soft young myope no normal soft young hypermetrope no normal soft pre-presbyopic myope no normal soft pre-presbyopic hypermetrope no normal soft presbyopic hypermetrope no normal soft
尊重劳动者的知识产权,请打上出处:http://python.jobbole.com/63320/