我们已经学习过数字类型和字符串类型,为了更好地学习余下的几种类型,有必要对python中的对象类型进行小结。在总结过后,将发现,剩下的类型学习起来会很轻松。所以可以很快地学习列表和字典。
总结过后,继续我们的对象之旅。
----------------------------------------------------------------------------------------------
可以从三个角度对类型进行分类:一是对象类型本身,二是操作的限制,三是是否有序。当然这些分类不
能包含所有类型,如布尔型
Ⅰ四大类型
数字(整数、浮点数、二进制数、分数、小数等)
支持C语言传统运算
序列(字符串、列表、元组)
支持索引、分片和合并等运算
映射(字典)
支持键的索引等
集合
一个自成一体的运算,支持大多数的数学集合的运算(写python的人是数学家?)
Ⅱ两类对立的限制
不可变类型(数字、字符串、元组、不可变集合)
不可变类型不支持在对象本身上修改,但是可以根据原有对象创建一个可修改的其它类型对象以达到改变原有对象的目的。任何你看起来发生了变化的对象,都是与原对象形似的新对象。
可变类型(列表、字典、可变集合)
可以在原处修改,而不用创建新对象。
Ⅲ有序与无序
有序类型(数字,字符串、列表、元组等)
当内部元素顺序发生改变时,这个对象已经不再是原对象。有序类型,往往可以通过相对位置来索引。
无序类型(集合,字典等)
无序类型内部元素没有固定顺序,所以重复打印时,它们看起来会有所不同。无序类型或者通过键来索引,或者转变为其他类型来索引。
----------------------------------------------------------------------------------------------
列表
列表是任意对象的有序可变的集合(不是集合类型)。
任意对象,列表内部的对象是任意的,列表内部的对象实质上是对象引用。有序,可以通过偏移量来索引,可以执行分片合并操作。可变,对象长度可变,并且可以在原处修改。
列表操作
对照字符串类型,列表类型的操作将很容易理解,二者的不同之处在于可变性。
>>> L = [] #空列表
>>> L = ["ab", 3.14, [2,4,6],{"ag",6.26}] #包含了各种类型的对象
>>> L
['ab', 3.1400000000000001, [2, 4, 6], {6.2599999999999998, 'ag'}]
>>> L = [[1,2,3],[4,5,6],[7,8,9]] #包含了多维数组
>>> L[1] #索引
[4, 5, 6]
>>> L[1][2] #二重索引
6
>>> L = ["abcdefghi",3.14,("real","imag"),[1,2,3,4]]
>>> L[0:2] #分片
['abcdefghi', 3.1400000000000001]
>>> L[0][1:5] #分片与索引
'bcde'
>>> L[1] = {"name":"Lucy"} #原处修改
>>> L
['abcdefghi', {'name': 'Lucy'}, ('real', 'imag'), [1, 2, 3, 4]]
>>> L = ["ag",[1,4],{"a"}]
>>> M = [{"class":"two"}]
>>> L M #合并
['ag', [1, 4], {'a'}, {'class': 'two'}]
>>> M*3 #重复
[{'class': 'two'}, {'class': 'two'}, {'class': 'two'}]
列表方法调用
可以用help(list)或dir(list)查看
>>> dir(list)
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
>>> L = ["qwwr",87]
>>> M = [32,[1,3,4]]
>>> len(L),len(M) #长度
(2, 2)
>>> L.append([3,4]) #追加
>>> L
['qwwr', 87, [3, 4]]
>>> L.extend([2]) #扩展
>>> L
['qwwr', 87, [3, 4], 2]
>>> L.insert(87,("real","imag")) #插入
>>> L
['qwwr', 87, [3, 4], 2, ('real', 'imag')]
>>> L.index(87) #求索引号
1>>> L.reverse() #翻转
>>> L
[('real', 'imag'), 2, [3, 4], 87, 'qwwr']
>>> L.remove(("real","imag")) #删除元素
>>> L
[2, [3, 4], 87, 'qwwr']
>>> del L[1] #根据索引号删除
>>> L
[2, 87, 'qwwr']
>>> L[0]=str(L[0]) #格式化
>>> L[1]=str(L[1])
>>> L
['2', '87', 'qwwr']
>>> L.reverse() #翻转
>>> L
['qwwr', '8', '2']
列表迭代与解析(简单展示)
>>> L = [c*4 for c in "spam"]
>>> L
['ssss', 'pppp', 'aaaa', 'mmmm']
>>> list(map(ord, ["s","p","a","m"]))
[115, 112, 97, 109]
----------------------------------------------------------------------------------------------
字典(dictionary)
字典是任意对象的,无序的,可变的集合;它是一种映射类型,即它的元素是键值对(key-value);作为一种灵活的内置类型,它在搜索算法上有着明显优势,因为字典本质上就是散列表(hash)。
字典的基本样式是:{key1:value1, key2:value2,......}
创建字典
简单赋值的方法
>>> D = {} #空字典
>>> D = {"spam":2, "eggs":3}
>>> D = {"spam":2, "eggs":3, 3:4, (1,2):"butter"} #键值可以为任意对象
>>> D
{(1, 2): 'butter', 'eggs': 3, 3: 4, 'spam': 2}
>>> D = {"spam":2, "set":{"animal":"dog", "plant":"tree"}} #可以嵌套
>>> D
{'set': {'plant': 'tree', 'animal': 'dog'}, 'spam': 2} #无序
动态添加
>>> D = {}
>>> D["name"] = "jack" #每次添加一个键值对
>>> D["age"]=15
>>> D["position"] = (23, 78, 190)
>>> D
{'position': (23, 78, 190), 'age': 15, 'name': 'jack'}
dict函数:关键字与值
>>> D = dict(name="jim", age=14, postion=(123,345,20))
>>> D
{'age': 14, 'postion': (123, 345, 20), 'name': 'jim'} #关键字自动转换为字符串
dict函数:键值元组
>>> D = dict([("name","age"), ("jim",14)])
>>> D
{'jim': 14, 'name': 'age'}
dict.fromkeys方法:如果想让值都为某个值可以用这个方法,因此此法适合初始化
>>> D = dict.fromkeys(["name","age"],0)
>>> D
{'age': 0, 'name': 0}
zip函数:将键列表和值列表一一映射为字典
>>> D = dict(zip(["name","age"],["jack",14]))
>>> D
{'age': 14, 'name': 'jack'}
字典索引---通过键名访问值
keys索引:字典不是通过相对位置,而是通过键名来访问值
>>> D = {"name":"jack", "age":14, "position":(1,234,56)}
>>> D["position"] #键名类似于C数组的下标,发扬了shell
(1, 234, 56) #数组的精神
>>> position="position"
>>> D[position]
(1, 234, 56)
修改字典:字典被修改时不会像字符串那样创建新的对象,而只是在原对象上的修改
>>> D = {}
>>> D[1] = "start" #动态添加是一种基本的修改方式
>>> D
{1: 'start'}
>>> D["second"] = 2
>>> D
{1: 'start', 'second': 2}
>>> D[1] = "first" #对键索引后赋值,直接修改
>>> D
{1: 'first', 'second': 2} #删除
>>> del D["second"]
>>> D
{1: 'first'}
显然,字典作为一种内置对象类型有一套修改它的方法
>>> dir(dict)
['__class__', '__contains__', '__delattr__', '__delitem__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
>>> D = {"name":"jack", "age":14, "***":"male"}
>>> D.get("age") #索引
14
>>> print(D.get("position")) #missing-key
None
>>> print(D.get("position", (12,34,56)))
(12, 34, 56)
>>> D
{'age': 14, 'name': 'jack', '***': 'male'}
>>> d = {"class":1}
>>> D.update(d) #合并
>>> D
{'class': 1, 'age': 14, 'name': 'jack', '***': 'male'}
>>> D.pop("name") #删除
'jack'
>>> D
{'class': 1, 'age': 14, '***': 'male'}
>>> dictionay = D.copy() #复制
>>> dictionay
{'age': 14, 'class': 1, '***': 'male'}
字典解析:与C/C++的不同之处
字典解析是python独特的语法,它可以用来创建,初始化与修改字典
>>> D = {k:v for (k,v) in zip(["a", "b", "c"], [1, 2, 3])} #创建字典
>>> D
{'a': 1, 'c': 3, 'b': 2}
>>> D = {x:x*x for x in range(1, 5)} #很像一般的集合解析
>>> D
{1: 1, 2: 4, 3: 9, 4: 16}
>>> D = {key:0 for key in ["a","b","c"]} #批量初始化,与fromkeys方法类似
>>> D
{'a': 0, 'c': 0, 'b': 0}
>>> list(D.keys())
['a', 'c', 'b']
>>> D = {key:key.upper() for key in D.keys()} #修改
>>> D
{'a': 'A', 'c': 'C', 'b': 'B'}
字典视图(dictionary views):keys,values与items的视图方法返回的是可迭代的视图对象
>>> K = D.keys()
>>> K
dict_keys(['a', 'c', 'b']) #可迭代但并非列表
>>> list(K)
['a', 'c', 'b']
>>> V = D.values()
>>> list(V)
['A', 'C', 'B']
>>> I = D.items()
>>> list(I)
[('a', 'A'), ('c', 'C'), ('b', 'B')]
>>> for value in V:print(value,end="\n")
A
C
B
字典视图对象类似于集合,并且支持集合的交集并集等运算,但是values视图除外,因为它不是唯一的
>>> D = {1:1, 2:1, 3:1,4:1}
>>> list(D.values())
[1, 1, 1, 1] #显然不符合集合元素的要求
>>> D = {k:v for (k,v) in zip(["a","b","c","d"],[1,2,3,4])}
>>> D
{'a': 1, 'c': 3, 'b': 2, 'd': 4}
>>> dic = {"a":1, "d":9}
>>> D.keys() | dic.keys() #keys并集
{'a', 'c', 'b', 'd'}
>>> D.keys() & dic.keys() #keys交集
{'a', 'd'}
>>> D.items() | dic.items()
{('a', 1), ('d', 9), ('b', 2), ('c', 3), ('d', 4)}
>>> D.items() & dic.items()
{('a', 1)}
>>> D.keys() - dic.keys() #差集
{'c', 'b'}
由于视图对象不是列表,所以无法直接排序,但是可以将其转化为列表再用sorted()
>>> D = {2:1, 0:3, 4:7, 1:9}
>>> sorted(list(D.values()))
[1, 3, 7, 9]
>>> sorted(list(D.keys()))
[0, 1, 2, 4]
>>> sorted(list(D.items()))
[(0, 3), (1, 9), (2, 1), (4, 7)]
其他注意事项:
Ⅰ字典不支持直接比较大小,但是可以:sorted(D1.items())> sorted(D2.items());但是相等测试r任然
有效
Ⅱ字典支持in方法,并且不再支持2.x中的has_key方法
Ⅲ 字典可以模拟列表:可以把字典键名设置为列表相对位置索引,这样就可以获得更灵活的结构
例如:
>>> D = {}
>>> D[99] = "spam"
>>> D
{99: 'spam'}
>>> L = []
>>> L[99] = "spam" #试图对第100项赋值,但是产生错误
Traceback (most recent call last): #因为此项还不存在,L长度仅是0
File "
", line 1, in
L[99] = "spam"
IndexError: list assignment index out of range
>>> len(L)
0