基于股票大数据分析的Python入门实战(视频教学版)
上QQ阅读APP看书,第一时间看更新

2.3 通过字典存放“键-值对”类型的数据

Python中的字典(Dict)也是数组的一种,在其中能以“键-值对”(Key-Value Pair)的方式存放多个数据。在字典中,是用基于哈希表的方式来保存数据,所以数据查找的速度非常快,哪怕其中存储的数据再多,也能以O(1)的计算复杂度找到数据,即基本是一次查找就命中。

和其他程序设计语言一样,Python中的字典一般是用来存储多个数据,而不是一个。

2.3.1 针对字典的常见操作

字典主要用来存储“键-值对”的数据,在DictDemo.py范例程序中,展示了在项目中的常见操作字典的用法。

1    # !/usr/bin/env python
2    # coding=utf-8
3    # 定义并打印字典
4    onePersonInfo={'name': 'Mike', 'age': 7}
5    print(onePersonInfo)             # {'age': 7, 'name': 'Mike'}
6    onePersonInfo['age']=8             # 修改其中的元素
7    print(onePersonInfo)             # age会变成8
8    print(onePersonInfo['name'] )     # Mike
9    del onePersonInfo['name']
10    print(onePersonInfo)                 # age会变成8 #{'age': 8}
11    print(onePersonInfo.get('name'))     # None
12    print(onePersonInfo.get('age'))     # 8
13    if 'name' not in onePersonInfo:
14        onePersonInfo['name']="Mike"     # 增加新元素
15    print(onePersonInfo.get('name'))     # Mike
16    # 通过for循环遍历字典
17    for i,v in onePersonInfo.items():
18        print(i,v) # 得到键和值

在上述范例程序中的第4行是通过大括号(即{})来定义字典,而且是通过冒号的方式来定义“键-值对”,比如用'name': 'Mike'的形式,即表示name这个键的值是Mike。请注意,多个“键-值对”之间是用逗号分隔。

在第6行中,演示了可以通过方括号的方式来访问onePersonInfo这个字典类型中的'age'键,并把它的值改成8,通过第7行的打印语句就能看到这一修改后的结果。

可以像第9行那样用del语句,还是通过方括号的形式,删除字典中指定的“键-值对”,完成删除后,如果通过第11行的get语句来获取'name',则会返回None,即表示没找到对应的值。这里get的作用是获取字典中指定键对应的值,比如在第12行中,可以通过get,输出'age'这个键对应的值。

还可以通过in和not in来判断在字典里有没有指定的键,比如在第13行中,在if语句中用not in来判断onePersonInfo这个字典里是否有'name',由于之前在第9行中已经删除了这个键,因此这里执行第14行的代码,在字典里增加'name'等于"Mike"这个“键-值对”。

在第17行和18行中,通过for循环遍历了onePersonInfo字典,其中值得关注的是,首先是通过items方法获取字典中所有的“键-值对”,其次是在for循环中通过i和v来映射字典中的“键-值对”。第17行程序语句中的i和v的变量名可以随便起,和第18行print语句中保持一致即可。

2.3.2 在字典中以复杂的格式存储多个数据

在2.3.1小节中,我们在字典中存放了一条关于人的信息,比如名字叫Mike,年龄是7岁。而在实际项目中,往往会在字典中存储相同数据类型格式的多个数据,而且还会出现在字典中嵌套了列表等的复杂用法。在下面的DictMoreData.py范例程序中将演示这些用法。

1    # !/usr/bin/env python
2    # coding=utf-8
3    # 以列表方式定义Mike和Tom两个人的账户
4    accountsInfoList=[{'name': 'Mike', 'balance': 100,'stockList':['600123','600158']},{'name': 'Tom', 'balance': 200,'stockList':['600243','600558']} ]
5    # 通过for循环,依次输出列表中的元素
6    for item in accountsInfoList:
7        print(item['name'],)    # print后带逗号表示不换行
8        print(item['balance'],)
9        print(item['stockList'])
10    # 以字典的方式定义
11    accountInfoDict={ 'Peter':{'balance': 100,'stockList':['600123', '600158'] },'Tom': { 'balance': 200,'stockList':['600243','600558']} }
12    # 输出{'balance': 100, 'stockList': ['600123', '600158']}
13    print(accountInfoDict.get('Peter'))
14    PeterAccount={ 'Peter':{'balance': 200,'stockList':['600223','600158',600458] }}
15    accountInfoDict.update(PeterAccount)
16    print(accountInfoDict.get('Peter')) # 能看到更新后的内容
17    JohnAccount={ 'John':{'balance': 200,'stockList':[] }}
18    accountInfoDict.update(JohnAccount)
19    # 利用双层循环打印
20    for name,account in accountInfoDict.items():
21        print ("name is %s:"%(name)),     # 输出name后不换行
22        for key,value in account.items():
23            print(value,)
24        Print() # 输完一个人的信息后换行

在第4行中用方括号的方式定义了accountsInfoList列表对象,在其中用大括号的方式定义了两个“键-值对”类型的账户信息,在第6行到第9行的for循环里,依次输出了这两个账户信息里的三个“键-值对”,输出的结果如下所示:

    Mike 100 ['600123', '600158']
Tom 200 ['600243', '600558']

在第11行中用大括号的方式定义了accountInfoDict这个字典类型的数据,其中同样存放了两个人的账户信息。在实际项目的集合对象中,不可能只存储一个数据,大家要掌握这种用列表或字典保存多个数据的方式。

字典对象中的另一个比较实用的方法是update,它有两层含义,如果字典对象中已经有相同的键,那么就用对应的值更新原来的值。比如在第14行中,更新了Peter的balance和stockList信息,在第15行的update语句中,就会用第14行中定义的对应值(即balance和stockList)更新掉原来的值,通过第16行的print语句就能看到这一更新后的结果。

update语句另外的一层含义是,如果在字典中没有待更新的“键”,那么就会插入对应的“键-值对”。比如在第17行中,定义原本不存在于accountInfoDict字典对象的JohnAccount,一旦执行了第18行的update语句就会完成更新,后面的打印语句即可看到插入更新后的结果。

由于在accountInfoDict这个字典类对象中存储了结构比较复杂的对象,比如值也是字典类型,而stockList是列表类型,因此在20行到第24行中用双层for循环来遍历这个字典对象。

其中,在第21行中输出了每个字典中的“键”,即姓名信息,输完后不换行。在第22行的内层for循环里调用了item方法,依次遍历了accountInfoDict对象中的“值”信息(也是字典类型的对象),遍历完一个人的账户信息后,会在第24行中通过print语句进行换行,这段语句的输出结果如下,其中包含新增的John的账户信息。

    name is Peter: 200 ['600223', '600158', 600458]
    name is John: 200 []
name is Tom: 200 ['600243', '600558']

虽然可以在字典中存放各种类型的数据,但应当用同一种格式存储多个数据,比如在第11行中用'name':{'balance': xx, 'stockList':[xx]}的格式输入并存储多个人的账户信息。

这样做的好处是,由于事先约定好能用同一种方式来解析字典中的数据,因此解析数据的规则是统一的。这点在Java等语言中能用泛型来保证,但在Python语言中,如果两个数据的格式不一致,也不会出现语法错误,但这样的做法就会造成处理方式的不统一。所以在使用Python字典类对象时,程序员应当时刻注意这点。