和其余编程语言相比,什么才是Python举世无双的特色呢?很多程序员会说,缩进。确实,缩进是Python语言的标志性特点,但这只是外在的、模式上的。从语言个性层面讲,Python的特点是什么呢?我尝试着在知乎上搜寻了一下,最具代表性的答案别离是语法简洁、简略易学、代码高效、功能强大等四项。认真品尝这四项,我还是感觉,这是Python语言体现进去的应用成果或用户感触,依然不是语言个性层面的特色。

换个说法,到底是Python的哪些语言个性使得人们普遍认为Python具备语法简洁、简略易学、代码高效、功能强大的特点呢?我集体认为,这要归功于列表(list)、字典(dict)、元组(tuple)和汇合(set)这“四大金刚”。只管整型(int)、浮点型(float)和字符串(str)也很重要,但这三种对象绝对于其余编程语言来说,差别并不像“四大金刚”那样显著。能够毫不夸大地说,列表、字典、元组和汇合代表了Python语言的外围和根底,同时也是Python的精华所在。学会应用列表、字典、元组和汇合,就意味着把握了Python这门编程语言。

如果认可这个观点,那么,Python的精华就从列表、字典、元组和汇合等“四大金刚”,演变成由方括号、花括号和圆括号组成的“括号族”。

1. 方括号
方括号简直是所有编程语言的第一符号。这里的第一,并不是指应用频率,而是指这个符号展现出的编程语言的外延和创造力。事实上,就符号的应用频率而言,方括号也可能排在首位——只是我的直觉,并没有统计数据反对。

1.1 创立列表
对于初学者来说,创立列表最罕用的办法就是用一对方括号。

>>> a = []>>> a[]>>> b = [3.14, False, 'x', None]>>> b[3.14, False, 'x', None]

即使是老鸟,也会大量应用方括号创立列表,尤其是应用推导式创立列表的状况下。

>>> c = [i**2 for i in range(5)]>>> c[0, 1, 4, 9, 16]

但我始终感觉,方括号就像书面语或俚语,太过轻易。我更喜爱应用谨严的list()来创立列表。应用list()创立列表,是list类的实例化的规范办法,能够领会list类的构造函数如何适应不同类型的参数。

>>> a = list()>>> a[]>>> b = list((3.14, False, 'x', None))>>> b[3.14, False, 'x', None]>>> c = list({1,2,3})>>> c[1, 2, 3]>>> d = list({'x':1,'y':2,'z':3})>>> d['x', 'y', 'z']>>> e = list(range(5))>>> e[0, 1, 2, 3, 4]>>> f = list('*'*i for i in range(5))>>> f['', '*', '**', '***', '****']

1.2 列表的索引
方括号能够创立列表,但方括号并不等同于列表,因为方括号还用来索引。

>>> [3.14, False, 'x', None][2]'x'>>> [3.14, False, 'x', None][-2]'x'>>> [3.14, False, 'x', None][1:][False, 'x', None]>>> [3.14, False, 'x', None][:-1][3.14, False, 'x']>>> [3.14, False, 'x', None][::2][3.14, 'x']>>> [3.14, False, 'x', None][::-1][None, 'x', False, 3.14]

列表的索引非常灵活,尤其是引入了正数索引,用-1示意最初一个元素或逆序,实属喜大普奔。下面的操作,属于罕用索引形式,如果能读懂上面的代码,阐明你曾经具备了足够深的功力。

>>> a = [3.14, False, 'x', None]>>> a[2:2] = [1,2,3]>>> a[3.14, False, 1, 2, 3, 'x', None]

1.3 列表的办法
对于列表对象的办法如果能信手拈来,那就是Python高手了。

>>> a = [3.14, False, 'x', None]>>> a.index('x')2>>> a.append([1,2,3])>>> a[3.14, False, 'x', None, [1, 2, 3]]>>> a[-1].insert(1, 'ok')>>> a[3.14, False, 'x', None, [1, 'ok', 2, 3]]>>> a.remove(False)>>> a[3.14, 'x', None, [1, 'ok', 2, 3]]>>> a.pop(1)'x'>>> a[3.14, None, [1, 'ok', 2, 3]]>>> a.pop()[1, 'ok', 2, 3]>>> a[3.14, None]

2. 花括号
花括号代表字典对象,大多数初学者都这样认为。然而,这是谬误的,至多是全面的。上面的代码中,a和b都是用花括号发明进去的对象,却一个是字典,一个是汇合。

>>> a = {}>>> a{}>>> b = {'x','y','z'}>>> b{'y', 'z', 'x'}>>> type(a)<class 'dict'>>>> type(b)<class 'set'>

原来,Python用花括号示意字典和汇合两种对象:花括号内是空的,或者是键值对的,示意字典;花括号内是无反复元素的,示意汇合。为了不引起误会,我习惯用dict()来生成字典,用set()来生成汇合。

>>> dict(){}>>> dict({'x':1, 'y':2, 'z':3}){'x': 1, 'y': 2, 'z': 3}>>> dict((('x',1), ('y',2), ('z',3))){'x': 1, 'y': 2, 'z': 3}>>> dict.fromkeys('xyz'){'x': None, 'y': None, 'z': None}>>> dict.fromkeys('abc', 0){'a': 0, 'b': 0, 'c': 0}>>> set((3,4,5)){3, 4, 5}>>> set({'x':1, 'y':2, 'z':3}){'y', 'z', 'x'}>>> set([3,3,4,4,5,5]){3, 4, 5}

编码实际中,尽管在某些状况下汇合是无可替代的,但汇合的应用频率是“四大金刚”中最低的,咱们这里不展开讨论,只说说字典的应用技巧。

2.1 判断一个键是否存在于字典中
Py2时代,dict对象已经有has_key()的办法,用来判断是否蕴含某个键。py3舍弃了这个办法,判断一个键是否存在于字典中,只能应用in这样的办法了。

>>> a = dict({'x':1, 'y':2, 'z':3})>>> 'x' in aTrue>>> 'v' in aFalse

2.2 向字典中增加一个新键或更新键值
很多人喜爱用对字典的一个键赋值的办法,实现向字典中增加一个新键或更新键值。

>>> a = dict()>>> a['name'] = 'xufive'>>> a{'name': 'xufive'}

我不举荐这样的形式,应用update()才更有典礼感,还能够一次增加或批改多个键。

>>> a = dict()>>> a.update({'name':'xufive', 'gender':'男'})>>> a{'name': 'xufive', 'gender': '男'}

2.3 从字典中获取一个键值
a['age']是最罕用的形式,然而也还会遇到键不存在的异样。上面的办法值得举荐。

>>> a.get('age', 18)18

2.4 获取字典的全副键、全副值、全副键值对
dict类提供了keys()、values()和items()等三个办法别离返回字典的全副键、全副值和全副键值对。须要留神的是,返回后果并非列表,而是迭代器。如果你须要列表模式的返回后果,请应用list()转换。

>>> a = dict()>>> a.update({'name':'xufive', 'gender':'男'})>>> list(a.keys())['name', 'gender']>>> list(a.values())['xufive', '男']>>> list(a.items())[('name', 'xufive'), ('gender', '男')]

2.5 遍历字典
遍历字典的时候,很多同学或写成遍历字典的keys()。其实,不须要这么麻烦,能够像上面这样间接遍历。

>>> a = dict([('name', 'xufive'), ('gender', '男')])>>> for key in a:        print(key, a[key])name xufivegender 男

3. 圆括号
圆括号代表元组对象,这么说应该没有问题吧?确实,听起来没有问题,但在元组的应用上,我置信每个初学者都会跌进同一个深坑至多一次。

3.1 必入之浅坑
元组不用于列表的最显著的特点,就是无奈更新元素的值。遗记或者疏忽这一点,就会入坑。

>>> a = (3, 4)>>> a[0] = 5Traceback (most recent call last):  File "<pyshell#14>", line 1, in <module>    a[0] = 5TypeError: 'tuple' object does not support item assignment

3.2 必入之深坑
应用了多年Python之后,我已经写出的最蹩脚的bug,就是上面这一段代码。

>>> import threading>>> def do_something(name):        print('My name is %s.'%name)>>> th = threading.Thread(target=do_something, args=('xufive'))>>> th.start()Exception in thread Thread-1:Traceback (most recent call last):  File "C:\Users\xufive\AppData\Local\Programs\Python\Python37\lib\threading.py", line 926, in _bootstrap_inner    self.run()  File "C:\Users\xufive\AppData\Local\Programs\Python\Python37\lib\threading.py", line 870, in run    self._target(*self._args, **self._kwargs)TypeError: do_something() takes 1 positional argument but 6 were given

我明显只提供了1个参数,却提醒说给出了6个参数,为什么呢?原来,元组初始化时,如果只有单个参数,则必须在单个参数之后减少一个逗号(,),否则,初始化后果仅返回原参数。

>>> a = (5)>>> a5>>> type(a)<class 'int'>>>> b = ('xyz')>>> b'xyz'>>> type(b)<class 'str'>>>> a, b = (5,), ('xyz',)>>> a, b((5,), ('xyz',))>>> type(a), type(b)(<class 'tuple'>, <class 'tuple'>)

3.3 单星号解包元组
格式化输入字符串时,C语言格调是我的最爱。当有多个%须要匹配时,上面兴许是最自然而然的写法。

>>> args = (95,99,100)>>> '%s:语文%d分,数学%d分,英语%d分'%('天元浪子', args[0], args[1], args[2])'Python编程学习圈:语文95分,数学99分,英语100分'

正确诚然正确,但不够精彩。满分写法应该是这样的。

>>> args = (95,99,100)>>> '%s:语文%d分,数学%d分,英语%d分'%('Python编程学习圈', *args)'Python编程学习圈:语文95分,数学99分,英语100分'

3.4 为什么要应用元组?
既然元组的元素不可扭转,那为什么还要应用元组呢?应用列表代替元组不是更不便吗?诚然,在少数状况下,能够应用列表代替元组,但上面的例子却能够证实,列表无奈代替元组。

>>> s = {1,'x',(3,4,5)}>>> s{1, (3, 4, 5), 'x'}>>> s = {1,'x',[3,4,5]}Traceback (most recent call last):  File "<pyshell#32>", line 1, in <module>    s = {1,'x',[3,4,5]}TypeError: unhashable type: 'list'

咱们能够将元组加到汇合中,但列表不行,因为列表是不可哈希(unhashable)的。了解这一点并不艰难:列表元素能够被动静扭转,所以没有一个固定不变的哈希值——这与汇合要求的元素唯一性抵触;而元组的元素被禁止更新,其哈希值在整个生命周期都不会变动,因而能够成为汇合的元素。

显然,元组和列表有着齐全不同的存储形式。因为不必思考更新问题,元组的速度性能要远优于列表。优先应用元组,应该成为Python程序员遵循的一条根本准则。

以上就是本次分享的所有内容,想要理解更多 python 常识欢送返回公众号:Python 编程学习圈 ,发送 “J” 即可收费获取,每日干货分享