40个你可能不知道的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 = 1, 2

>>> a, b = b, a

>>> a, b

(2, 1)

    3、扩展的拆箱(Python 3支持)

>>> a, *b, c = [1, 2, 3, 4, 5]

>>> a

1

>>> b

[2, 3, 4]

>>> c

5

    4、负数索引

>>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

>>> a[-1]

10

>>> a[-3]

8

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

>>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

>>> a[2:8]

[2, 3, 4, 5, 6, 7]

    6、负数索引的列表切片

>>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

>>> a[-4:-2]

[7, 8]

    7、带步数的列表切片(a[start:end:step])

>>> 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]

    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]

    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]

    10、切片命名(slice(start, end, step))

>>> a = [0, 1, 2, 3, 4, 5]

>>> LASTTHREE = slice(-3, None)

>>> LASTTHREE

slice(-3, None, None)

>>> a[LASTTHREE]

[3, 4, 5]

    11、遍历列表索引和值(enumerate)

>>> a = ["Hello", "world", "!"]

>>> for i, x in enumerate(a):

... print "{}: {}".format(i, x)

...

0: Hello

1: world

2: !

    12、遍历字典的KEY和VALUE(dict.iteritems)

>>> m = {"a": 1, "b": 2, "c": 3, "d": 4}

>>> for k, v in m.iteritems():

... print "{}: {}".format(k, v)

...

a: 1

c: 3

b: 2

d: 4

# 注意:Python 3中要使用dict.items

    13、压缩 & 解压列表和可遍历对象

>>> 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")]

    14、使用zip分组相邻列表项

>>> a = [1, 2, 3, 4, 5, 6]

>>> # Using iterators

>>> 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,)]

>>> # Using slices

>>> from itertools import islice

>>> group_adjacent = lambda a, k: zip(*(islice(a, i, None, 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,)]

    15、使用zip & iterators实现推拉窗(n-grams)

>>> from itertools import islice

>>> def n_grams(a, n):

... z = (islice(a, i, None) 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)]

    16、使用zip反相字典对象

>>> 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"}

    17、合并列表

>>> 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]

Note: according to Python"s documentation on sum, itertools.chain.from_iterable is the preferred method for this.

    18、生成器

>>> 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

    19、字典解析

>>> 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"}

    20、使用字典解析反相字典对象

>>> 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"}

    21、命名的tuples(collections.namedtuple)

>>> Point = collections.namedtuple("Point", ["x", "y"])

>>> p = Point(x=4.0, y=2.0)

>>> p

Point(x=4.0, y=2.0)

>>> p.x

4.0

>>> p.y

2.0

    22、继承命名tuples

>>> 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=4.0, y=2.0)

>>> q = Point(x=2.0, y=3.0)

>>> p + q

Point(x=6.0, y=5.0)

    23、Set & Set运算

>>> A = {1, 2, 3, 3}

>>> A

set([1, 2, 3])

>>> 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])

>>> A - B

set([1, 2])

>>> B - A

set([4, 5, 6, 7])

>>> A ^ B

set([1, 2, 4, 5, 6, 7])

>>> (A ^ B) == ((A - B) | (B - A))

True

    24、Multisets运算(collections.Counter)

>>> 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})

    25、列表中出现最多的元素(collections.Counter)

>>> 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(3)

[(3, 4), (1, 2), (2, 2)]

    26、双向队列(collections.deque)

>>> 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])

    27、限制长度的双向队列(collections.deque)

>>> 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

    28、排序字典(collections.OrderedDict)

>>> 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

    29、默认字典(collections.defaultdict)

>>> 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]"

    30、使用defaultdict代表tree

>>> 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"

}

}

# 查看更多:https://gist.github.com/hrldcpr/2012250

    31、映射对象到唯一的计数数字(collections.defaultdict)

>>> 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

    32、最大 & 最小元素(heapq.nlargest and heapq.nsmallest)

>>> 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]

    33、笛卡尔积(itertools.product)

>>> 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

    34、组合(itertools.combinations and itertools.combinations_with_replacement)

>>> 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

    35、排列(itertools.permutations)

>>> 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

    36、链接可遍历对象(itertools.chain)

>>> 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)

    37、根据给定的KEY分组(itertools.groupby)

>>> from operator import itemgetter

>>> 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 " ".join(" ".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=itemgetter(-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

    38、在任意目录启动HTTP服务

python -m SimpleHTTPServer 5000

Serving HTTP on 0.0.0.0 port 5000 ...

    39、Python之禅

>>> import this

The Zen of Python, by Tim Peters

Beautiful is better than ugly.

Explicit is better than implicit.

Simple is better than complex.

Complex is better than complicated.

Flat is better than nested.

Sparse is better than dense.

Readability counts.

Special cases aren"t special enough to break the rules.

Although practicality beats purity.

Errors should never pass silently.

Unless explicitly silenced.

In the face of ambiguity, refuse the temptation to guess.

There should be one-- and preferably only one --obvious way to do it.

Although that way may not be obvious at first unless you"re Dutch.

Now is better than never.

Although never is often better than *right* now.

If the implementation is hard to explain, it"s a bad idea.

If the implementation is easy to explain, it may be a good idea.

Namespaces are one honking great idea -- let"s do more of those!

    40、使用C风格的大括号代替Python缩进来表示作用域

>>> from __future__ import braces


你可能感兴趣的:(python,技巧)