Python编程语言的35个与众不同之处(语言特征和使用技巧)


Posted in Python onJuly 07, 2014

一、Python介绍

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

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

二、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.zip打包解包列表和倍数
>>> 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')]

12.使用zip合并相邻的列表项
>>> 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.使用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)]

14.使用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'}

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]

 

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

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: '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'}

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

19.命名序列 (collections.namedtuple)
>>> 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

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

Point(x=3.0, y=5.0)

21.集合及集合操作
>>> 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

22.多重集及其操作 (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})

23.迭代中最常见的元素 (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)]

24.双端队列 (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])

25.有最大长度的双端队列 (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

26.字典排序 (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

27.缺省字典 (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]'

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"

    }

}

 

(到https://gist.github.com/hrldcpr/2012250查看详情)

29.映射对象到唯一的序列数 (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

30.最大最小元素 (heapq.nlargest和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]

31.笛卡尔乘积 (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

32.组合的组合和置换 (itertools.combinations 和 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

33.排序 (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

34.链接的迭代 (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)

35.按给定值分组行 (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 '\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=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 
Python 相关文章推荐
一篇不错的Python入门教程
Feb 08 Python
Python Tkinter GUI编程入门介绍
Mar 10 Python
在Python 3中实现类型检查器的简单方法
Jul 03 Python
python中根据字符串调用函数的实现方法
Jun 12 Python
Python使用PyCrypto实现AES加密功能示例
May 22 Python
python中利用xml.dom模块解析xml的方法教程
May 24 Python
Python2.7下安装Scrapy框架步骤教程
Dec 22 Python
基于树莓派的语音对话机器人
Jun 17 Python
python的slice notation的特殊用法详解
Dec 27 Python
解决python多线程报错:AttributeError: Can't pickle local object问题
Apr 08 Python
判断Threading.start新线程是否执行完毕的实例
May 02 Python
Python爬虫+tkinter界面实现历史天气查询的思路详解
Feb 22 Python
python基于mysql实现的简单队列以及跨进程锁实例详解
Jul 07 #Python
python中使用urllib2获取http请求状态码的代码例子
Jul 07 #Python
Python中使用urllib2防止302跳转的代码例子
Jul 07 #Python
python中使用urllib2伪造HTTP报头的2个方法
Jul 07 #Python
python实现多线程采集的2个代码例子
Jul 07 #Python
Python程序员开发中常犯的10个错误
Jul 07 #Python
python采用requests库模拟登录和抓取数据的简单示例
Jul 05 #Python
You might like
MySQL的FIND_IN_SET函数使用方法分享
2012/03/27 PHP
CodeIgniter连贯操作的底层原理分析
2016/05/17 PHP
JS实多级联动下拉菜单类,简单实现省市区联动菜单!
2007/05/03 Javascript
js window.onload 加载多个函数和追加函数详解
2014/01/08 Javascript
js控制input框只读实现示例
2014/01/20 Javascript
jquery easyui 对于开始时间小于结束时间的判断示例
2014/03/22 Javascript
javascript 模拟坦克大战游戏(html5版)附源码下载
2014/04/08 Javascript
jQuery构造函数init参数分析
2015/05/13 Javascript
创建自己的jquery表格插件
2015/11/25 Javascript
js创建数组的简单方法
2016/07/27 Javascript
对layui中表单元素的使用详解
2018/08/15 Javascript
jQuery实现模拟搜索引擎的智能提示功能简单示例
2019/01/27 jQuery
详解Vue+ElementUI从零开始搭建自己的网站(一、环境搭建)
2019/04/30 Javascript
浅谈对于“不用setInterval,用setTimeout”的理解
2019/08/28 Javascript
Vue中的循环及修改差值表达式的方法
2019/08/29 Javascript
vue实现修改图片后实时更新
2019/11/14 Javascript
Python计算斗牛游戏概率算法实例分析
2017/09/26 Python
django限制匿名用户访问及重定向的方法实例
2018/02/07 Python
python实现一个函数版的名片管理系统过程解析
2019/08/27 Python
win10环境下配置vscode python开发环境的教程详解
2019/10/16 Python
解决tensorflow添加ptb库的问题
2020/02/10 Python
Python Dataframe常见索引方式详解
2020/05/27 Python
基于keras中的回调函数用法说明
2020/06/17 Python
CSS3实现淘宝留白的方法
2020/06/05 HTML / CSS
求职者简历中的自我评价
2013/10/20 职场文书
班组长的岗位职责
2013/12/09 职场文书
考察现实表现材料
2014/05/19 职场文书
2014年教师节寄语
2014/08/11 职场文书
委托书怎样写
2014/08/30 职场文书
2015年安全生产目标责任书
2015/01/29 职场文书
公司2015年终工作总结
2015/05/26 职场文书
学历证明范文
2015/06/16 职场文书
科级干部培训心得体会
2016/01/06 职场文书
《伯牙绝弦》教学反思
2016/02/16 职场文书
婚前协议书怎么写,才具有法律效力呢 ?
2019/06/28 职场文书
Go中的条件语句Switch示例详解
2021/08/23 Golang