列表、字典、元组进阶
列表、字典和元组是python中所有脚本的主要工作组件。
列表
列表中可包含任意种类的对象。和字符串一样,他也支持序列的常规操作,指定偏移值和切片、合并以及迭代等序列操作。
与其他语言不同的是列表是一种高阶的序列操作工具,python中的列表可以完成大多数几何体数据结构的工作。
列表的主要属性:
1.任意对象的有序集合:列表中收集任何python对象并且保持了从左往右的位置顺序;
2.通过偏移量读取;
3.可变长度、异构和任意长度:列表是可变数据类型,支持原处修改,其中元素可以是任意数据类型,包括列表字典。
4.对象引用:python总是会存储对象的引用而不是对象的copy。
注:我们在学习时注重精通常量语法,但是现实生产中python的多数据结构都是建立在运行执行程序代码时。
列表的常规操作:
a=[1,2,'a'] b=['a','s','d'] print(a+b) print(a*2) 运行结果: [1, 2, 'a', 'a', 's', 'd'] [1, 2, 'a', 1, 2, 'a']
列表的迭代与解析:
for i in a: print(i**2) 运行结果: 1 4 9
a=[1,2,3] print(i**2 for i in a) print(list(i**2 for i in a)) 运行结果: <generator object <genexpr> at 0x00000000027EBB40> [1, 4, 9]
a=[-1,2,3] print(list(map(abs, a))) 运行结果: [1, 2, 3]
由于列表多次嵌套,所以有时需要多次索引才能深入到数据结构中。
a=[[1,2,3], [4,5,6], [7,8,9]] print(a[2][1]) 运行结果: 8
切片赋值时被赋值序列长度可以与我们复制的序列长度不相同,故可以用此操作进行替换,插入,缩短主列表。并且赋值的值与切片重合也是切实可行的。例:a[2:5]=a[3:7]。
列表的常用方法:
append():与a+[x]不同的是,方法原地修改列表,而+会产生新的列表。所以append方法执行更快。
a=[1,2,3] a.append(4) print(a) 运行结果: [1, 2, 3, 4]
sort():可以给定配置选项,name=value来定义。
a=['aBC','abd','Abe'] a.sort() print(a) a.sort(key=str.upper,reverse=True) print(a) 运行结果: ['Abe', 'aBC', 'abd'] ['Abe', 'abd', 'aBC']
注:在python2中比较时int总比str小,比较运算并不会自动转换类型,到了python3以后类型之间有了明确的界限,[1,2,'a']这用列表已经不可以用sort方法排序了。
a=['aBC','abd','Abe'] print(sorted(a)) 运行结果: ['Abe', 'aBC', 'abd']
其他常用方法:
a=['aBC','abd','Abe'] a.extend(['a']) print(a) 运行结果: ['aBC', 'abd', 'Abe', 'a']
a=['aBC','abd','Abe'] a.pop() print(a) 运行结果: ['aBC', 'abd']
a=['aBC','abd','Abe'] a.reverse() print(a) print(list(reversed(a))) 运行结果: ['Abe', 'abd', 'aBC'] ['aBC', 'abd', 'Abe']
a=['aBC','abd','Abe'] a.insert(0,'a') print(a) print(a.index('a')) a.remove('a') print(a) print(a.pop(1)) 运行结果: ['a', 'aBC', 'abd', 'Abe'] 0 ['aBC', 'abd', 'Abe'] abd
注:a[i:j]=[]可以做到删除,但是a[i]=[]只会将此索引位置改为空列表。
字典:
字典是一种无序的集合,是靠key来取值的序列。字典可以非常快速的进行一些其他语言的搜索算法和数据结构。
字典的主要属性:
1.通过key而不是偏移量取值:字典有自己的hash表,通过键来取值。
2.任意对象无需集合:字典并没有特定的顺序,实际上key提供了象征性的位置作用。
3.与列表一样字典可变长、异构、任意嵌套。
4.属于可变映射类型。
5.对象引用表:采用最优化的散列算法来寻找key,搜索速度极快,并且与列表一样存储对象是引用而不是拷贝。
字典的常用操作:
a={'name':'jeff','age':'111'} print(list(a.keys())) 运行结果: ['name', 'age']
a={'name':'jeff','age':'111'} print('name' in a) 运行结果: Ture
a={'name':'jeff','age':'111'} a['name']='frank' print(a) 运行结果: {'name': 'frank', 'age': '111'}
a={'name':'jeff','age':'111'} a['like']='game' print(a) 运行结果: {'name': 'jeff', 'like': 'game', 'age': '111'}
a={'name':'jeff','age':'111'} a['like']='game' del a['like'] print(a) 运行结果: {'age': '111', 'name': 'jeff'}
字典常用方法:
a={'name':'jeff','age':'111'} print(list(a.values())) print(list(a.items())) 运行结果: ['jeff', '111'] [('name', 'jeff'), ('age', '111')]
get():检查key是否在,并返回某个值,默认None。
a={'name':'jeff','age':'111'} print(a.get('name','no')) print(a.get('like','no')) 运行结果: jeff no
update():更新没有的,并且盲目覆盖已有的值。
a={'name':'jeff','age':'111'} a.update({'like':'game'}) print(a) 运行结果: {'name': 'jeff', 'like': 'game', 'age': '111'}
pop():
a={'name':'jeff','age':'111'} a.pop('age') print(a) 运行结果: {'name': 'jeff'}
注:字典的键不一定都是字符串,当然不可能是列表啦,字典的键可以是任何不可变对象。
小技巧:制作一个字典让他用起来很像一个列表。
a={0:'jeff',1:'111'} print(a[0]) 运行结果: jeff
值得一提的是读取不存在的键时常会报错,而在一些场景我们并不希望报错,我们可以采取以下三种方式进行避免:
1.if先对键进行判断再使用。
a={0:'jeff',1:'111'} if 2 in a: print(a[0]) else: print('none') 运行结果: none
2.try语句修复
a={0:'jeff',1:'111'} try: print(a[2]) except KeyError: print('none') 运行结果: none
3.get()
a={0:'jeff',1:'111'} print(a.get(2,'none')) 运行结果: none
字典取代了搜索数据结构,在嵌套时轻松表达结构化信息。
注:字典接口适用于python各种内置工具。
字典的4中创建方法:
a={0:'jeff',1:'111'} print(a) 运行结果: {0: 'jeff', 1: '111'}
a={} a['name']='jeff' print(a) 运行结果: {'name': 'jeff'}
a=dict(name='jeff') print(a) 运行结果: {'name': 'jeff'}
a=dict([('name','jeff')]) print(a) 运行结果: {'name': 'jeff'}
如果事先就能拼出整个字典,就使用第一种创建方式,如果需要动态创建字典的某个字段则使用第二种方式,第三种方式的key必须是字符串,第四种方式需要在运行时把key好的value逐步建成序列。
python3中字典做出了哪些改变:
1.支持字典解析表达式;
2.调用a.keys、a.values、a.items方法需要使用list使其可视化;
3.不再支持大小比较,相等性测试依然存在;
4.取消has_key方法,只使用in判断成员关系,当然get方法也是可行的。
字典解析:
a={k:v for (k,v) in zip([1,2,3],['a','s','d'])} print(a) 运行结果: {1: 'a', 2: 's', 3: 'd'}
keys,values,items返回的都是可迭代视图对象,如果想用列表操作或者显示他们的值,必须通过内置函数list来完成。当然这种试图既然是可迭代对象,我们还可以使用for循环迭代查看。此外遍历key的方法直接使用for i in {}即可,不一定要是用key方法。并且python3可以动态反映在视图创建对象后对字典做出的修改。
注:python2keys不会反回一个列表,所以python2需要通过排序键来浏览一个字典的编码模式。
小练习:创建字典,所有键的value都是0。
a={'a':0,'b':0...} print(a)
a={} a['a']=0 a['b']=0 . . . print(a)
a=dict(a=0,b=0...) print(a)
a=dict([('a',0),('b',0)...]) print(a)
a=dict.fromkeys(['a','b'...],0) print(a)
a={k:0 for k in 'ab...'} print(a)
元组
元组基本属性:
1.任意对象有序集合:这点与列表一致;
2.通过偏移存取;
3.固定长度、异构任意嵌套:因为元组是不可变序列类型;
4.引用对象而非copy。
元组和其他两种序列不同的是他没有方法,还是因为他的不可变性,可能根本就不需要什么方法吧。
这里值得注意的是定义只有单个元素的元组的情况:
a=('a') b=('a',) print(a) print(b) 运行结果: a ('a',)
在python里,括号在大所属情况下是可以忽略的,仅当元组作为常量穿个函数调用和元组在python2中print语句中列出时才必不可少。对于初学者可能对概念模糊不清,所以建议当前还是使用括号更好。
如果想要操作元组,可以将其转化为俩表对象进行操作,然后再转化为元组,在进行排序的操作时可以使用sorted函数来完成,此函数接受任何序列对象。
列表解析可以用于元组转换,列表解析甚至可以用在某些并非实际存储的序列之上,任何遍历对象都可以,包括逐行读取文件。
注:元组也不是完全没有方法,index和count在元组中也是可以工作的。并且元组的不可变性只是本身,不包括它内部的元素,如果元组的内部是列表元素,那他依然可以进行修改列表。
其他python对象及类型
篇幅有限简单介绍一下python的其他类型。
None对象
python特殊数据类型的唯一值,一般都起到一个空的占位作用。None不意味着无意义,None是某些内容,尽管是没有意义的意思,但是他是一个真正的对象,并且他有一块内存存放,python给定一个内置的名称。他还是函数的返回值。
bool类型
当明确地用在真值测试,真假就是1和0.交互模式下进行布尔测试结果也是打印成Ture与False。python内置函数bool()用于测试对象的真假。
type对象
即使是类型本身在python中也是有对象的。
print(type(type)) 运行结果: <class 'type'>
python还定义了isinstance来作为类型判断内置函数。
注:最后一点复合对象指向自身的引用,成为循环,python在对象中检测到循环就会打印成[...]而不会陷入无限的循环。
l=[1,2,3] l.append(l) print(l) 运行结果: [1, 2, 3, [...]]
除了这些核心对象以外,还有函数,模块和类的内核心数据类型,在之后的学习过程中,一一分享给大家。