Python_03-数据类型
1.1 数据类型
基本数据类型:字符串,整数,浮点数,布尔型
集合类型:列表(list), 元组(tuple), 字典(dictionary或hash)
列表(list)的定义:
aList = [23] 或者 bList = [1,2,3]
print bList[1]
List常用操作:append, del, + ,*, len(list)
[0] * 5
列表对象支持的方法
append(x)
count(x) :X在List中的个数
extend(L)
index(x)
insert(i,x)
pop(x)
remove(x)
reverse()
sort()
例子: list.append(x)#将元素x加入list列表
list.sort() 对列表list进行排序
元组(tuple)的定义:
aTuple = (1, 3, 5)
print aTuple
元组可以用方括号括起下标做索引
元组一旦创建就不能改变
列表大部分操作同样适用于元组
1.2 序列
1.2.1 sequence 序列
sequence(序列)是一组有顺序的元素的集合
(严格的说,是对象的集合,但鉴于我们还没有引入“对象”概念,暂时说元素)
序列可以包含一个或多个元素,也可以没有任何元素。
我们之前所说的基本数据类型,都可以作为序列的元素。
元素还可以是另一个序列,以及我们以后要介绍的其他对象。
序列有两种:tuple(定值表;也有翻译为元组)和 list (表)
>>>s1 = (2, 1.3, 'love', 5.6, 9, 12, False) # s1是一个tuple
>>>s2 = [True, 5, 'smile'] # s2是一个list
>>>print s1,type(s1)
>>>print s2,type(s2)
>>> s1 = (2, 1.3, 'love', 5.6, 9, 12, False)
>>> s1[0]
2
>>> type(s1[0])
<type 'int'>
>>> s1[2]
'love'
>>> type(s1[2])
<type 'str'>
>>> s1[3]
5.6
>>> type(s1[3])
<type 'float'>
tuple和list的主要区别在于,一旦建立,tuple的各个元素不可再变更,而list的各个元素可以再变更。
一个序列作为另一个序列的元素
>>>s3 = [1,[3,4,5]]
空序列
>>>s4 = []
1.2.2 元素的引用
>>>s3 = [1,[3,4,5]]
序列元素的下标从0开始:
>>>print s1[0]
>>>print s2[2]
>>>print s3[1][2]
由于list的元素可变更,你可以对list的某个元素赋值:
>>>s2[1] = 3.0
>>>print s2
如果你对tuple做这样的操作,会得到错误提示。
所以,可以看到,序列的引用通过s[<int>]实现, int为下标
1.2.3 其他引用方式
范围引用:基本样式[下限:上限:步长]
>>>print s1[:5] # 从开始到下标4 (下标5的元素不包括在内)
>>>print s1[2:] # 从下标2到最后
>>>print s1[0:5:2] # 从下标0到下标4 (下标5不包括在内),每隔2取一个元素(下标为0,2,4的元素)
>>>print s1[2:0:-1] # 从下标2到下标1
从上面可以看到,在范围引用的时候,如果写明上限,那么这个上限本身不包括在内。
1.2.4 尾部元素引用
>>>print s1[-1] # 序列最后一个元素
>>>print s1[-3] # 序列倒数第三个元素
同样,如果s1[0:-1], 那么最后一个元素不会被引用(再一次,不包括上限元素本身)
1.2.5 字符串是元组
字符串是一种特殊的元素,因此可以执行元组的相关操作。
>>>str = 'abcdef'
>>>print str[2:4]
总结
tuple元素不可变,list元素可变
序列的引用 s[2], s[1:8:2]
字符串是一种tuple
1.3 列表(list)
主要介绍了Python3的list列表用法, 这是Python3数据类型中非常常见的应用,
通常来说Python中任何值都是一个对象,因此任何类型(int、str、list…)都是一个类。而类就必然有它的方法或属性,我们要记下这么多类的所有方法显然是不可能的,对此本文介绍两个小技巧:
dir() :内置函数,用来查询一个类或者对象所有属性,比如>>> dir(list)。
help() :内置函数,用来查询具体的说明文档,比如>>> help(int)。
列表时对象的有序集合。列表的内容可以修改,列表的长度可变。
列表的定义:
<列表名称>[<列表项>]
其中多个列表项用逗号隔开,它们的类型可以相同,也可以不同,还可以是其列表。例如
date=[2011, 2, 9, 9, 54]
day=['sun','mon','tue','wed','thi','fri','sat']
today=[2011,2,9,"wed"]
data=[date,day]
均是合法的列表。 使用时,通过
<列表名>[索引号]
的形式应用,索引号从0开始,即0是第1项的索引号。例如date[0]的值是2011,day[1]得到“mon”,data[1][3]的到“wed”。下列程序:
date=[2011, 2, 9, 9, 54]
day=['sun','mon','tue','wed','thi','fri','sat']
today=[2011,2,9,"wed"]
data=[date,day]
print(date[0])
print(day[1])
print(data[1][3])
的运行结果为:
2011
mon
wed
列表可以整体输出,如print(data)
列表的其他运算见表1-2。
表1-2列表的运算
运算格式/举例 |
说明/结果 |
L1=[] |
空列表 |
L2=[ 2011, 2, 9, 19, 54] |
5项,整数列表,索引号0-4 |
L3= ['sun',['mon','tue','wed']] |
嵌套的列表 |
L2[i],L3[i][j] |
索引,L2[1]的值为2,L3[1][1]的值为'tue' |
L2[i:j] |
分片,取i到j-1的项 |
Len(L2) |
求列表的长度 |
L1+L2 |
合并 |
L2*3 |
重复,L2重复3次 |
for x in L2 |
循环,x取L2中的每个成员执行循环体 |
19 in L2 |
19是否是L2的成员 |
L2.append(4) |
增加4作为其成员,即增加一项 |
L2.sort() |
排序,L2结果变为[2, 9, 19, 54, 2011] |
L2.index(9) |
得到9在列表中的索引号,结果为2 |
L2.reverse() |
逆序,L2的结果为[2011, 54, 19, 9, 2] |
del L2[k] |
删除索引号为k的项 |
L2[i:j]=[] |
删除i到j-1的项 |
L2[i]=1 |
修改索引号为i的项的值 |
L2[i:j]=[4,5,6] |
修改i到j-1的项的值,如果项数多,则自动插入 |
L4=range(5,20,3) |
生成整数列表L4实际为[5,8,11,14,17] |
1.3.1 列表的方法
list.append(x)
在列表的尾部添加一个项,等价于 a[len(a):] = [x]。
list.extend(L)
将给定的列表L接到当前列表后面,等价于a[len(a):] = L。
list.insert(i, x)
在给定的位置 i 前插入项,例如:a.insert(0, x) 会在列表的头部插入,而 a.insert(len(a), x) 则等价于 a.append(x)。
list.remove(x)
移除列表中第一个值为 x 的项,没有的话会产生一个错误。
list.pop([i])
删除列表给定位置的项,并返回它。如果没指定索引,a.pop()移除并返回列表最后一项。(方括号表示可选)
list.clear()
删除列表中的所有项,相当于 del a[:]。
list.index(x)
返回列表中第一个值为
x 的项的索引。如果没有匹配的项, 则产生一个错误。
list.count(x)
返回列表中
x 出现的次数。
list.sort()
就地完成列表排序。
list.reverse()
就地完成列表项的翻转。
list.copy()
返回列表的一个浅拷贝,相当于a[:]。
1.3.2 列表当栈
List的方法使得其可以很方便地作为一个栈来使用。我们知道,栈的特点是最后进入的元素最先出来(即后入先出),用append()方法进行压栈,用不指定索引的pop()方法进行出栈。
示例代码如下:
stack = []
for x in range(1,6):
stack.append(x) # 入栈
print('push', x, ' ')
print(stack)
print('Now stack is', stack)
while len(stack)>0:
print('pop', stack.pop(), ' ') # 出栈
print(stack)
1.3.3 列表当队列
列表还可以当作队列来使用,队列的特性是第一个加入的元素第一个取出来(即先入先出)。然而,把列表当队列使用效率并不高,因为从列表的尾部添加和弹出元素是很快的,而在列表的开头插入或弹出是比较慢的(因为所有元素都得移动一个位置)。
要实现一个队列, 使用标准库的collections.deque,它被设计成在两端添加和弹出都很快。
示例代码如下:
from collections import deque
queue = deque() # 创建空队列
for x in range(1,6):
queue.append(x) # 入队
print('push', x, ' ')
print(list(queue))
print('Now queue is', list(queue))
while len(queue)>0:
print('pop', queue.popleft(), ' ') # 出队
print(list(queue))
1.3.4 列表推导式
列表推导式提供了从序列创建列表的简单途径。
通常程序会对序列的每一个元素做些操作,并以其结果作为新列表的元素,或者根据指定的条件来创建子序列。
列表推导式的结构是:在一个方括号里,首先是一个表达式,随后是一个 for 子句,然后是零个或更多的 for 或 if 子句。返回结果是一个根据表达从其后的 for 和 if 上下文环境中生成出来的列表。
示例代码如下:
squares
=
[x**2
for
x
in
range(10)] #
推导式
print(squares)
#
输出是[0, 1, 4, 9, 16, 25, 36, 49, 64,
81]
pairs
=
[(x, y) for
x in
[1,2,3]
for
y in
[3,1,4] if
x!=y] #
推导式
print(pairs)
#
输出是[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
1.3.5 列表嵌套
Python中并没有二维数组的概念,但我们可以通过列表嵌套达到同样的目的。
mat = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
print(mat)
print(type(mat))
print(mat[1])
mat[2]=[0,0,0]
print(mat)
同样,我们可以使用推导式生成嵌套的列表:
mat = [[1,2,3], [4,5,6], [7,8,9]]
new_mat = [ [row[i] for row in mat] for i in [0,1,2] ] # 嵌套
print(new_mat)
# 输出[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
附:del语句
del语句可以通过给定索引(而不是值)来删除列表中的项,它与返回一个值的pop()方法不同。del语句也可以移除列表中的切片,或者清除整个列表:
lst
=
[1,2,3,4,5,6,7,8,9]
del
lst[2] #
删除指定索引项
print(lst)
del
lst[2:5] #
删除切片
print(lst)
del
lst[:]
#
删除整个列表
print(lst)
del
也可以用于删除变量实体:
del
lst
在删除变量实体之后引用 lst 的话会产生错误。
1.4 元组(tuple)
元组和列表十分类似,只不过元组和字符串一样是不可变的,即不能修改元组。元组通过圆括号中用逗号分割的项目定义。当一组数据,只使用,不修改时使用元组。元组的使用与列表相同,只是不能修改、删除、增加其元素。例如:
# use of tuple
# filename: tuple.py
garden=("Bird of Paradise" ,"rose" ,"tulip", "lotus","olive", "Sunflower")
print ('Number of flowers in the garden is', len(garden))
i=2;
print('flower',i,'is',garden[i-1])
new_garden = ('Phlox', 'Peach Blossom', garden)
i=1;
print('flower',i,'is',garden[i-1])
运行结果如下:
C:\Python31>python tuple.py
Number of flowers in the garden is 6
flower 2 is rose
flower 1 is Bird of Paradise
元组的运算见表1-3
表1-3元组的运算
运算格式/举例 |
说明/结果 |
T1() |
空元组 |
T2=(2011,) |
有一项的元组 |
T3=(2011, 2, 9, 19, 54) |
5项,整数元组,索引号0-4 |
T4= ('sun',('mon','tue','wed')) |
嵌套的元组 |
T3[i],T4[i][j] |
索引,T3[1]的值为2,T4[1][1]的值为'tue' |
T3[i:j] |
分片,取i到j-1的项 |
Len(T3) |
求元组的长度 |
T3+T4 |
合并 |
T3*3 |
重复,T3重复3次 |
for x in T3 |
循环,x取T3中的每个成员执行循环体 |
19 in T3 |
19是否是L2的成员 |
注意:元组与列表的最大不同:一是定义时用一对圆括号,二是内容不能修改。
1.5 字典(dict)
字典是python中唯一内置映射数据类型。
通过指定的键从字典访问值,即 [key,value]模式
字典为容器,内建len函数可以将字典当作单一参数使用,返回字典对象中项目(键/值对)的数目。
字典是无序的对象的集合,通过键进行操作。类似于通讯录,通过姓名来查找电话、地址等信息,则姓名就是键。一定要没有同名的人。
字典的定义为:
<字典名>={键1:值2,键2:值2,键3:值3,…}
其中,键1,键2,键3不相同,值可以是任何类型的数据,可以是列表或元组。注意,字典定义中使用的是大括号,项通过逗号隔开,每个项有键部分和值部分,键和值之间用冒号隔开。只可使用简单的对象作为键,而且不能改变,但可以用不可变或可变的对象作为字典的值。
在Python2.2以及后面版本,D中的k运算符检测是否对象k是字典D中的键。如果是返回True如果不是返回False。相似的,
字典D中的值与相关的键k被索引表示为:D[k]。索引字典没有的键会引起意外。例如:
d = { 'x':42, 'y':3.14, 'z':7 }
d['x'] # 42
d['z'] # 7
d['a'] # raises exception
1.5.1 赋值
D[newkey]= value 该操作加载键和值到字典里新的项目中。
1.5.2 删除
语法:
del D[k]中的del语句,删除字典中拥有键k的项目。
如果k不是字典D中的键,del D[k]就会引起意外。
1.5.3 字典的使用例子
a = {'a': 'aa', 'b': 'bb'}
a['c']='cc'
a.has_key('a') #判断字典中是否存在此值
a['a']='uu'
a
a['a']=3
del a['a'] #删除键值
a
len(a)
示例:
>>> d={'d':[3,4],1:[7],'ab':['ab','cd','ef']}
>>> d['d']
[3, 4]
>>> d[1]
[7]
>>> d['ab']
['ab', 'cd', 'ef']
>>> print(d)
{1: [7], 'd': [3, 4], 'ab': ['ab', 'cd', 'ef']}
>>> del d[1]; print(d)
{'d': [3, 4], 'ab': ['ab', 'cd', 'ef']}
1.5.4 字典的常用方法
has_key(x)
keys()
values()
items()
clear()
copy()
update(x)
get(x[,y])
1.5.5 示例
例如:
# use of dictionaries
# filename: dict.py
address1 = {'zhang' : 'larry@wall.org',
'wang' : 'wang@wall.org',
'lily' : 'lily@ruby-lang.org',
'sam' : 'sam@hotmail.com'
}
print ('mail of zhang',address1['zhang'])
address2 = {'zhang' : ['larry@wall.org','shaanxi'],
'wang' : ['wang@wall.org','beijing'],
'lily' : ['lily@ruby-lang.org','shanghai'],
'sam' : ['sam@hotmail.com','hubei']
}
print ('mail of zhang',address2['lily'][0])
print ('province of zhang',address2['lily'][0])
运行结果如下:
C:\Python31>python dict.py
mail of zhang larry@wall.org
mail of zhang lily@ruby-lang.org
province of zhang lily@ruby-lang.org
字典的操作见表1-4:
表1-4字典的运算
运算格式/举例 |
说明/结果 |
d1={} |
空字典 |
d2={'class':'jianhuan','year':'2011'} |
有两项的字典 |
d3={'xjtu':{'class':'huagong','year':'2011'}} |
字典的嵌套 |
d2['class'], d3['xjtu']['class'] |
按键使用字典 |
d2.keys() |
获得键的列表 |
d2.values() |
获得值的列表 |
len(d2) |
求字典的长度 |
d2['year']=2020 |
添加或改变字典的值 |
del d2['year'] |
删除键 |
1.6 Python 序列应用
序列:成员有序排列,并且可以通过下标漂移量访问一个(直接指定索引)或者几个成员(切片操作)。
包括字符串(普通字符串和unicode字符串)、列表和元组。其索引第一个元素从零向后递增(正索引),也可以从最后一个元素的-1索引向前递减(负索引)。
1.6.1 所有的标准类型操作符适用于序列
(值比较操作符,对象身份比较,逻辑操作符)。
1.6.2 序列类型的操作符
(1)成员关系操作符(in, not in)
判断一个元素是否属于一个序列,返回值为True/False。
(2)连接操作符(+)
将一个序列与另一个相同类型的序列做连接。
这个方法并不是最快最有效的,因为python要为每一个参加连接操作的字符串分配新的内存,包括新产生的字符串。对于字符串,推荐将子字符串放到一个列表或者可迭代对象中,调用join方法连接,节约内存。对于列表,推荐使用列表对象的extend()方法。
示例:
>>> t1=['ab','cd','ef']
>>> t2=[3,4,5]
>>> t1.extend(t2)
>>> t1
['ab', 'cd', 'ef', 3, 4, 5]
(3)重复操作符(*)
一个序列的多份拷贝,返回一个包含多份原对象拷贝的新对象。sequence*copies_int,注意copies_int必须为整型,不能为长整型。
(4)切片操作符([],[:][::])
访问某一个数据元素:sequence[index]。(len()函数可获得序列的长度)
例:print ('a','b','c')[1] (例子中没有先赋值直接访问一个序列的元素,当只对函数返回序列对象的某些元素感兴趣时非常有用)
访问多个元素:sequence[starting_index:ending_index]。(注意不包括结束索引,并且如果没有提供或者用None作索引值,则从第一个元素开始或者到最后一个元素结束)。对于这种形式,起始索引和结束索引可以为超过字符串长度的索引。
例:s[:-1] 从第一个元素到最后一个元素
s[:0] 返回''
扩展的步长索引:
例:s[::-1] 可以看作翻转操作,'abcd'操作后为'dcba'
例:
s='abcde'
for i in [None] + range(-1, -len(s),-1)
print s[:i]
(注意这里不能先用None生成列表,再用extend将range的输出加入列表,因为extend的输出为None)
1.6.3 序列常用的内建函数
(1)类型转换:实际上没有进行真正的类型转换,是将参数传入对象的内容浅拷贝到新生成的对象中。浅拷贝是指只拷贝对象的索引,不是重新建立对象,在python中,对象建立后就不能更改其身份和类型。
str():用于对象的打印,对序列类型和其它类型都适用。
unicode():功能与str()一样,只是输出为unicode编码。
list():转换为列表;tuple():转换为元组。这两个函数常用于列表和元组的互换。很少用于string类型。
basestring():抽象工厂函数,是str和unicode的父类,不能被实例化和调用。
(2)内建函数:
参数只接收序列对象:len(seq),reversed(seq),sum(seq,start)。
参数可接收序列对象和可迭代对象:
enumerate(iter)
sorted(iter,func=None,key=None,reverse=False),
zip([it0,it1,...itN])
可接收参数列表:
max(iter,key=None)或者max(arg0,arg1,...,key=None)
min类同于max。