什么是 Python?
Python 是一种计算机程序设计语言。你可能已经听说过很多种流行的编程语言,比如非常难学的 C 语言,非常流行的 Java 语言,适合初学者的 Basic 语言,适合网页编程的 JavaScript 语言等等。
那 Python 是一种什么语言?
首先,我们普及一下编程语言的基础知识。用任何编程语言来开发程序,都是为了让计算机干活,比如下载一个 MP3,编写一个文档等等,而计算机干活的 CPU 只认识机器指令,所以,尽管不同的编程语言差异极大,最后都得“翻译”成 CPU 可以执行的机器指令。而不同的编程语言,干同一个活,编写的代码量,差距也很大。
比如,完成同一个任务,C 语言要写 1000 行代码,Java 只需要写 100 行,而 Python 可能只要 20 行。
所以 Python 是一种相当高级的语言。
你也许会问,代码少还不好?代码少的代价是运行速度慢,C 程序运行 1 秒钟,Java 程序可能需要 2 秒,而 Python 程序可能就需要 10 秒。
那是不是越低级的程序越难学,越高级的程序越简单?表面上来说,是的,但是,在非常高的抽象计算中,高级的 Python 程序设计也是非常难学的,所以,高级程序语言不等于简单。
但是,对于初学者和完成普通任务,Python 语言是非常简单易用的。连 Google 都在大规模使用 Python,你就不用担心学了会没用。
用 Python 可以做什么?可以做日常任务,比如自动备份你的 MP3;可以做网站,很多著名的网站包括 YouTube 就是 Python 写的;可以做网络游戏的后台,很多在线游戏的后台都是 Python 开发的。总之就是能干很多很多事啦。
Python 当然也有不能干的事情,比如写操作系统,这个只能用 C 语言写;写手机应用,只能用 Swift/Objective-C(针对 iPhone)和 Java(针对 Android);写 3D 游戏,最好用 C 或 C++。
本篇教程将讲述 Python 基础的数据类型。
数据的基本类型
在 Python 中,能够直接处理的数据类型有以下几种:
整数
Python 可以处理任意大小的整数,包括负整数,写程序的时候表述与数学上的方法一样,例如:99,-3,6666 等等。
浮点数
浮点数也可以称为小数。叫做浮点数是因为按照科学记数法表示时,一个浮点数的小数点位置是可变的。比如,1.11×106和11.1×105是完全相等的。对于很大或很小的浮点数,必须用科学计数法表示,把 10 用 e 替代,1.11×106就是1.11e6,或者11.1e5,0.0000011可以写成1.1e-6。负数的话直接在前面加负号即可,例如:-1.1e-6。
需要注意的一点是,整数和浮点数在计算机内部存储的方式是不同的,整数之间的运算永远是精确的,而浮点数运算则可能会有四舍五入的误差。
字符串
字符串是以单引号 ‘ 或双引号 ” 括起来的任意文本’ ‘或” “只是一种表示方式,不是字符串的一部分,所以字符串’rice’只有r,i,c,e这 4 个字符。如果要把’本身也包括进字符里,那就可以用” “括起来。如果字符串内部既包含 ‘ 又包含 ” 怎么办呢?我们可以用转义字符 \ 来标识,例如:’I’m “OK”!’表示的内容为:I’m “OK”!
转义字符\可以转义很多字符,比如\n表示换行,\t表示制表符,字符 \ 本身也要转义,所以 \ 表示的字符就是 \ ,用 print()打印字符串看看结果如何:
In [1]: print('I\'m \"OK\"!')
Out [1]: I'm "OK"!
In [2]: print('CHINA SECURITIES is\ngreat')
Out [2]: CHINA SECURITIES is
great
In [3]: print('\\\t\\\')
Out [3]: \ \
布尔值
布尔值和布尔代数的表示完全一致,一个布尔值只有True、False两种值。Python 中,既可以直接用True、False表示(一定要大写),也可以通过布尔运算计算出来:
In [4]: True
Out [4]: True
In [5]: False
Out [5]: False
In [6]: 1>0
Out [6]: True
布尔值可以用and、or和not即与、或和非进行运算。
In [7]: True and False
Out [7]: False
In [8]: 1 > 2 or 3 < 10
Out [8]: True
In [9]: not 3 < 10
Out [9]: False
列表
Python 内嵌的数据类型主要包括以下两类:
有序:
List(列表),是有序集合,没有固定大小,可以通过对偏移量以及其他方法修改列表大小。列表的基本形式如:[1,2,3,4]
Tuple(元组),是有序集合,是不可变的,可以进行组合和复制运算后会生成一个新的元组。元组的基本形式比如:(1,3,6,10)
String(字符串),也是有序集合,字符串的基本形式比如:’hello’,这里不进行具体介绍。
无序:
Set(集合),是一个无序不重复元素的集。基本功能包括关系运算和消除重复元素。集合的基本形式如:set(‘abracadabra’)
Dictionary(字典)是无序的键:值对 (key:value 对)集合,键必须是互不相同的(在同一个字典之内)。字典的基本形式如:{‘jack’: 4098, ‘sape’: 4139} 首先对列表进行介绍。
List(列表) 是 Python 中最通用的序列。列表是一个任意类型对象位置的相关有序集合,它没有固定大小。不像字符串,其大小是可以变的,通过对偏移量进行赋值以及其他各种列表的方法进行调用,可以修改列表大小。
索引是从 0 开始而非 1 开始!!
列表中值的分割用变量[头下标:尾下标],就可以截取相应的列表,从左到右索引默认“0”开始的,从右到左索引默认-1 开始,下标可以为空表示取到头或尾。可以对列表进行索引、切片等操作,看下面例子。
列出一周 5 个工作日可以使用 list:
In [10]: week = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
week
Out [10]: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
week 是一个 list,可以用 len()获取其元素个数:
In [11]: len(week)
Out [11]: 5
可以使用索引来访问 list 中的每一个位置上的元素,不过一定要记住索引是从 0 开始的!!
In [12]: week[0]
Out [12]: 'Monday'
In [13]: week[3]
Out [13]: 'Thursday'
In [14]: week[5]
Out [14]: ---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-14-aab97e4d2f9f> in <module>()
----> 1 week[5]
IndexError: list index out of range
当索引超出了范围时,Python 会报一个IndexError错误。由于索引是从0开始的,最后一个元素的索引是列表长度 – 1。
python 支持从列表最后取元素,如果要取最后一个元素,可以用-1 做索引,直接获取最后一个元素:
In [15]: week[-1]
Out [15]: 'Friday'
In [16]: week[-4]
Out [16]: 'Tuesday'
由于 list 是一个可变的有序表,所以我们可以往 list 中追加元素到末尾:
In [17]: week.append('Saturday')
week
Out [17]: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
还可以吧元素插入到指定的位置,比如索引号为6的位置:
In [18]: week.insert(6, 'Sunday')
week
Out [18]: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
删除 list 末尾的元素,使用pop()方法:
In [19]: week.pop()
week
Out [19]: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
删除 list 中指定位置的元素,使用pop(i)方法,i 是对应的索引位置:
In [20]: week.pop(1)
week
Out [20]: ['Monday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
把某个元素替换成别的元素,可以直接赋值给对应的索引位置:
In [21]: week[0] = 'Tuseday'
week
Out [21]: ['Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
Python 的列表数据类型包含更多的方法。
list.append(x) 把一个元素添加到列表的结尾。
list.extend(L) 将一个给定列表中的所有元素都添加到另一个列表中。
list.insert(i, x) 在指定位置插入一个元素。第一个参数是准备插入到其前面的那个元素的索引,例如 a.insert(0, x) 会插入到整个列表之前,而 a.insert(len(a), x) 相当于 a.append(x)。
list.remove(x) 删除列表中值为 x 的第一个元素。如果没有这样的元素,就会返回一个错误。
list.pop([i]) 从列表的指定位置删除元素,并将其返回。如果没有指定索引,a.pop() 返回最后一个元素。元素随即从链表中被删除。(方法中 i 两边的方括号表示这个参数是可选的,而不是要求你输入一对方括号,这个经常会在 Python 库参考手册中遇到这样的标记。)
list.index(x) 返回列表中第一个值为 x 的元素的索引。如果没有匹配的元素就会返回一个错误。
list.count(x) 返回 x 在链表中出现的次数。
list.sort(cmp=None, key=None, reverse=False) 对列表中的元素进行排序(参数可以用来自定义排序方法,参考 sorted() 的更详细的解释)。
list.reverse() 就地倒排链表中的元素
del list[i] 有个方法可以从列表中按给定的索引而不是值来删除一个子项:del 语句。它不同于有返回值的 pop() 方法。语句 del 还可以从列表中删除切片或清空整个列表(我们以前介绍过一个方法是将空列表赋值给列表的切片)。
字典(dictionary)
字典在某些语言中可能称为 联合内存 (associative memories) 或 联合数组 (associative arrays)。序列是以连续的整数为索引,与此不同的是,字典以”关键字”为索引,关键字可以是任意不可变类型,通常用字符串或数值。如果元组中只包含字符串和数字,它可以作为关键字,如果它直接或间接地包含了可变对象,就不能当做关键字。不能用列表做关键字,因为列表可以用索引、切割或者 append() 和 extend() 等方法改变。
字典是无序的键:值对 (key:value 对)集合,键必须是互不相同的(在同一个字典之内)。使用大括号创建一个空的字典:{}。初始化列表时,在大括号内放置一组逗号分隔的键:值对,这也是字典输出的方式。
字典的主要操作是依据键来存储和取值。也可以用 del 来删除键:值对(key:value),从一个不存在的键中取值会导致错误。
In [22]: d = {'rice':35, 'wheat':101, 'corn':67}
print(d)
print(d['rice'])
Out [22]: {'corn': 67, 'wheat': 101, 'rice': 35}
35
把数据放入 dict 还可以直接通过 key 放入:
In [23]: d['egg'] = 33
d
Out [23]: {'corn': 67, 'egg': 33, 'rice': 35, 'wheat': 101}
一个 key 只能对应一个 value,多次对一个 key 放入 value,后面的值会把前面的值冲掉:
In [24]: d['corn'] = 88
d
Out [24]: {'corn': 88, 'egg': 33, 'rice': 35, 'wheat': 101}
如果 key 不存在,dict 就会报错。要避免 key 不存在的错误,有两种办法,一是通过 in 判断 key 是否存在,二是通过 dict 提供的 get 方法,如果 key 不存在,可以返回 None(返回 None 的时候 Python 的交互式命令行不显示结果),或者自己指定的 value:
In [25]: d['meat']
Out [25]: ---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-25-d3e7ffd8023e> in <module>()
----> 1 d['meat']
KeyError: 'meat'
In [26]: 'meat' in d
Out [26]: False
In [27]: d.get('meat')
In [28]: d.get('meat', 45)
Out [28]: 45
删除一个 key,使用pop(key)方法,对应的 value 也会从 dict 中删除:
In [29]: d.pop('rice')
d
Out [29]: {'corn': 88, 'egg': 33, 'wheat': 101}
有下面几点需要注意:
- dict内部存放的顺序和key放入的顺序是没有关系的
- dict查找和插入的速度极快,不会随着key的增加而增加,但是需要占用大量的内存,内存浪费多
- dict的key必须是不可变对象。字符串、整数等都是不可变的,可以放心地作为key,而list是可变的,就不能作为key:
In [30]: k = [3, 4, 5]
d[k] = 6
Out [30]: ---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-30-725fccd6cc45> in <module>()
1 k = [3,4,5]
----> 2 d[k] = 6
TypeError: unhashable type: 'list'
常见字典操作方法
D.clear() 删除字典内所有元素
D.copy() 返回一个字典的复制
D.fromkeys(seq,val) 创建一个新字典,以序列 seq 中元素做字典的键,val 为字典所有键对应的初始值
D.get(key, default=None) 返回指定键的值,如果值不在字典中返回 default 值
D.has_key(key) 如果键在字典 dict 里返回 true,否则返回 false
D.items() 以列表返回可遍历的(键, 值) 元组数组
D.keys() 以列表返回一个字典所有的 D.keys()以列表返回一个字典所有的键
D.setdefault(key, default=None) 和 get()类似, 但如果键不存在于字典中,将会添加键并将值设为 default
D.update(dict2) 把字典 dict2 的键/值对更新到 dict 里
D.values() 以列表返回字典中的所有值
D.pop(key) 删除一个键并返回它的值,类似于列表的 pop,只不过删除的是一个键不是一个可选的位置
del D[key] 删除键
D[key] = 42 新增或修改键
字典用法注意事项:
- 序列运算无效,字典元素间是没有顺序的概念
- 对新索引赋值会添加项
- 键不一定总是字符串
多种构造字典方式
dict() 构造函数可以直接从 key-value 对中创建字典
In [31]: dict([('iohn', 4139), ('mike', 4127), ('lucy', 4098)])
Out [31]: {'john': 4139, 'lucy': 4098, 'mike': 4127}
In [32]: dict.fromkeys(['a', 'b'], 0) # 创建一个新字典,以序列seq中元素做字典的键,val为字典所有键对应的初始值
Out [32]: {'a': 0, 'b': 0}
In [33]: dict(zip['a', 'b', 'c'], [1, 2, 3])
Out [33]: {'a': 1, 'b': 2, 'c': 3}
In [34]: {k:v for (k, v) in zip(['a', 'b', 'c'], [1, 2, 3])
Out [34]: {'a': 1, 'b': 2, 'c': 3}
此外,字典推导式可以从任意的键值表达式中创建字典:
In [35]: {x: x**2 for x in (2, 4, 6)}
Out [35]: {2: 4, 4: 16, 6: 36}
如果关键字都是简单的字符串,有时通过关键字参数指定 key-value 对更为方便:
In [36]: D = dict(a=1, b=2, c=3)
D
Out [36]: {'a': 1, 'b': 2, 'c': 3}
In [37]: {c:c*4 for c in 'Zhongxinjiantou'} # 默认是集合
Out [37]: {'Z': 'ZZZZ',
'a': 'aaaa',
'g': 'gggg',
'h': 'hhhh',
'i': 'iiii',
'j': 'jjjj',
'n': 'nnnn',
'o': 'oooo',
't': 'tttt',
'u': 'uuuu',
'x': 'xxxx'}
In [38]: {c:c*4 for c in ['Zhongxinjiantou']}
Out [38]: {'Zhongxinjiantou': 'ZhongxinjiantouZhongxinjiantouZhongxinjiantouZhongxinjiantou'}
In [39]: {c.lower():c*4+'!' for c in 'Zhongxinjiantou'}
Out [39]: {'a': 'aaaa!',
'g': 'gggg!',
'h': 'hhhh!',
'i': 'iiii!',
'j': 'jjjj!',
'n': 'nnnn!',
'o': 'oooo!',
't': 'tttt!',
'u': 'uuuu!',
'x': 'xxxx!',
'z': 'ZZZZ!'}
元组(tuple)
tuple 是另一种有序的数据类型,与 list 比较类似。主要不同的一点是 tuple 被创建后就不能对其进行修改。所以,tuple 与 list 不同,没有 append(),pop(),insert()这些方法可以使用。获取元素的方法和 list 是一样的,可以通过索引来访问(也是从 0 开始的),只不过不能赋值成为其他的元素。
因为 tuple 不可变,所以代码更安全。如果可以的话,我们尽量使用 tuple 代替 list。
创造元组
定义一个空的 tuple,使用 () :
In [40]: t = ()
t
Out [40]: ()
只有 1 个元素的元组在进行定义的时候,需要加一个逗号 , 来消除歧义,否则定义的就不是一个元组而是元素本身:
In [41]: t = (3)
t
Out [41]: 3
In [42]: t = (3,)
t
Out [42]: (3,)
元组的连接
如前面所说,元组是不可改的,但是可以连接
可以使用 + 对元组进行连接,例如:
In [43]: t1 = (2,3,5)
t2 = ('Zhongxinjiantou', 'python')
t3 = t1 + t2
t3
Out [43]: (2, 3, 5, 'Zhongxinjiantou', 'python')
元组的删除
元组中的元素不能被删除,但是我们可以使用 del 删除整个元组,删除后可以重新定义:
In [44]: t4 = ('a', 2, 'b')
t4
Out [44]: ('a', 2, 'b')
In [45]: del t4
t4
Out [45]: ---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-45-00422465996d> in <module>()
1 del t4
----> 2 t4
NameError: name 't4' is not defined
事实上,上面所说的元素不变是指每个元素的指向永远不变。即指向1,就不能改成指向2,指向一个 list,就不能改成指向其他对象,但指向的这个 list 本身是可变的,例如:
In [46]: tup = (1, 2, [3, 4, 5])
tup
Out [46]: (1, 2, [3, 4, 5])
In [47]: tup[2][0] = 7
tup[2][1] = 11
tup
Out [47]: (1, 2, [7, 11, 5])
Python 的元组数据类型包含更多的方法。
tup.index(x, [start, [stop]])) 返回元组中 start 到 stop 索引中第一个值为 x 的元素在整个列表中的索引。如果没有匹配的元素就会返回一个错误。
tup.count(x) 返回 x 在元组中出现的次数。
cmp(tuple1, tuple2) 比较元组中两个元素。
len(tuple) 计算元组元素个数。
max(tuple) 返回元组中元素最大值。
min(tuple) 返回元组中元素最小值。
tuple(seq) 将列表转换为元组。
元组不提供字符串、列表和字典中的方法。 如果相对元组排序,通常先得将它转换为列表并使其成为一个可变对象,才能获得使用排序方法,或使用 sorted 内置方法。
集合(set)
与 dict 类似,set 也是一组 key 的集合,但不存储 value。由于 key 不能重复,所以,在 set 中,没有重复的 key。创建一个 set,需要提供一个 list 作为输入集合:
In [48]: s = set([3, 4, 5])
s
Out [48]: {3, 4, 5}
重复元素在 set 中会被自动被过滤,通过add(key)方法往 set 中添加元素,重复添加不会有效果,通过remove(key)方法可以删除元素,例如:
In [49]: s = set([3, 3, 4, 4, 5, 5, 6, 6, 7])
s
Out [49]: {3, 4, 5, 6, 7}
In [50]: s.add(1)
s
Out [50]: {1, 3, 4, 5, 6, 7}
In [51]: s.add(1)
s
Out [51]: {1, 3, 4, 5, 6, 7}
In [52]: s.remove(5)
s
Out [52]: {1, 3, 4, 6, 7}
由于 set 是无序和无重复元素的集合,所以两个 set 可以做数学意义上的交并集等操作:
In [53]: s1 = set([3, 4, 5, 6])
s2 = set([5, 6, 7, 8, 9])
s1 & s2
Out [53]: {5, 6}
In [54]: s1 | s2
Out [54]: {3, 4, 5, 6, 7, 8, 9}
与 dict 一样,set 同样不可以放入可变对象,因为无法判断两个可变对象是否相等,也就无法保证 set 内部不会有重复元素。所以把 list 放入 set,会报错。
In [55]: s = set([1, 2, [1, 2]])
Out [55]: ---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-55-806dee2b7dcf> in <module>()
----> 1 s = set([1,2,[1,2]])
TypeError: unhashable type: 'list
总结
总体而言,几种基础数据类型有相似之处,可根据实际应用场景来选择。