和其余编程语言相比,什么才是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 a
True
>>> 'v' in a
False
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 xufive
gender 男
3. 圆括号
圆括号表明元组对象,这么说应该没有问题吧?的确,听起来没有问题,但在元组的使用上,我相信每一个初学者都会跌进同一个深坑至少一次。
3.1 必入之浅坑
元组不用于列表的最显著的特色,就是没法更新元素的值。忘记或者忽略这一点,就会入坑。
>>> a = (3, 4)
>>> a[0] = 5
Traceback (most recent call last):
File "<pyshell#14>", line 1, in <module>
a[0] = 5
TypeError: '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
Custom Domain by Bitly()
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)
>>> a
5
>>> 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])
'天元浪子:语文95分,数学99分,英语100分'
[点击并拖拽以移动]
正确当然正确,但不够精彩。满分写法应该是这样的。
>>> args = (95,99,100)
>>> '%s:语文%d分,数学%d分,英语%d分'%('天元浪子', *args)
'天元浪子:语文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学习资料能够加QQ:2955637827私聊或加Q群630390733你们一块儿来学习讨论吧!shell