遍历字典元素:values、keys、items
使用 for i in d
:的方式遍历字典,i每次都是d中元素(键值对)的键,而不包括值。
字典的 values() 方法及应用
字典对象 values
方法:将该字典中所有元素(键值对)的值放入可迭代对象,从而可用for循环逐个读取。
values
方法返回的可迭代对象:
Python2中返回一个列表 Python3中是可迭代对象,不支持索引,也不支持next() Python3中返回的对象属于dictview()类型
二阶频次统计
a = ['张三','李四','张三','王五','张三','李四','张三','王五','王五','张三','赵六','赵六']
d = {i:a.count(i) for i in a}
d
{'张三': 5, '李四': 2, '王五': 3, '赵六': 2}
如何使用字典统计以下信息:
出现5次者1人
出现2次者2人
出现3次者1人
for i in d:
print(i)
张三
李四
王五
赵六
for i in d.values():
print(i)
5
2
3
2
for i in d:
print(d[i])
5
2
3
2
new_d = {i:list(d.values()).count(i) for i in d.values()}
new_d
{5: 1, 2: 2, 3: 1}
对于可迭代对象a:
list(a)根据a生成一个新的列表对象
tuple(a)根据a生成一个新的元组对象
set(a)根据a生成一个新的集合对象
dict(a)根据a生成一个新的字典对象
求取列表的“众数”——出现次数最多的那个元素
计算步骤
- 先算出每个元素的出现次数,存入字典d
- 用max函数算出d的所有值即 d.values() 中,最大数值是几
- 创建一个新字典,将d中符合条件的元素、即“值”等于“最大次数”的元素添加进来
a = ['A','B','A','C','B','C','B','B','C','D','C','D','E']
d = {i:a.count(i) for i in a}
maxv = max(d.values())
new_d = {i:d[i] for i in d if d[i] == maxv}
new_d
{'B': 4, 'C': 4}
字典的 keys() 和 items() 方法
字典对象的 keys()
方法与 values()
分相似,不过返回的是所有的键。
字典对象的 items()
方法也返回一个 dictview
,其中每个元素都是一个元组,包含字典中的一对键和值,比如 (‘A’, 2)。
for i in d.keys():
print(i)
A
B
C
D
E
for i in d.items():
print(i)
print(i[0], i[1])
('A', 2)
A 2
('B', 4)
B 4
('C', 4)
C 4
('D', 2)
D 2
('E', 1)
E 1
更简洁地使用 items()
for k, v in d.items()
# k 被赋值为键
# v 被赋值为值
for x, y in d.items():
print(x, y)
A 2
B 4
C 4
D 2
E 1
反向索引字典
d = {y:x for x, y in d.items()}
d
{2: 'D', 4: 'C', 1: 'E'}
d = {'张三':'091','李四':'092','王五':'087','赵六':'085'}
new_d = {y:x for x, y in d.items()}
new_d
{'091': '张三', '092': '李四', '087': '王五', '085': '赵六'}
解包
列表、元组、集合的解包:将等号左侧变量分别赋值为每个元素
字符串解包:将等号左侧变量分别赋值为每个字符
字典解包:将等号左侧变量分别赋值为每个键,没有值
d.items()
dict_items([('张三', '091'), ('李四', '092'), ('王五', '087'), ('赵六', '085')])
a, b, c = '甲乙丙'
a
'甲'
b
'乙'
c
'丙'
解包的特殊形式:多元赋值
同时将多个值赋给多个变量,即“多元赋值语句
”。常被用于交换变量数值
。
a, b = 1, 2
a
1
b
2
a = 3
b = 4
a, b = b, a # 相当于 a, b = 4, 3,自动解包并赋值
a
4
b
3
如果需要将元组、列表、字典、集合等容器中的元素取出来、并分别赋值给多个变量,只需在容器前标注星号,然后放到能够赋值的代码结构(比如赋值语句、for循环、调用函数时的参数值)中即可。比如:
a,b,c = [*(2, 5, 7)]
x = some_function( [*a_list] )
a, b, c = (2, 5, 7)
a
2
b
5
a,b,c = [*(3, 4, 5)]
a
3
b
4
a_list = (2, 5, 7)
x = sum([*a_list])
x
14
a_list = (2, 5, 7)
x = sum(a_list)
x
14
a,*b,*c = (1,2,3,4,5)
File "<ipython-input-68-cb60fc6d6f2b>", line 4
SyntaxError: two starred expressions in assignment
上式由于存在多种分配方案(即“歧义”),实际运行无法通过。
如果等号左侧变量数目多于右侧解包出来的元素个数,会导致程序错误。
如果等号左侧变量数目少于右侧解包出来的元素个数, Python2 中会导致程序错误;而 Python3 中则允许通过星号的方式正确赋值。
星号
星号的含义:将剩余内容放入列表,赋值给变量 星号可以加在任意变量前面 分配的规则:先处理位置明确的变量,然后再将剩余内容作为列表赋值给对应变量
【注意事项】 1.即使只剩一个元素,也会放入列表 2.如果剩余元素无法明确分配给多星号变量,则提示出错
打分 = [7.8,7.2,8.3,7.2,8.5,8.2,8.5,7.9]
最高分,*有效分,最低分 = sorted(打分)
有效分
[7.2, 7.8, 7.9, 8.2, 8.3, 8.5]
最高分
7.2
最低分
8.5
练习
练习1:字典汇总统计
首先下载 某企业ERP系统登录日志 工作簿文件。
请编写一个程序,使用 print 在屏幕上输出以下统计指标:
每位员工的登录次数;
登录次数最多的员工及其登录次数;
登录次数最少的员工及其登录次数。
import xlwings as xw
app = xw.App()
workbook = app.books.open('python02_16_01.xlsx')
worksheet = workbook.sheets[0]
worksheet
<Sheet [python02_16_01.xlsx]登录日志>
start_row = 3
end_row = 1003
names = []
for row in range(start_row, end_row):
row = str(row)
name = worksheet.range('C' + row).value
names.append(name)
workbook.close()
app.quit()
len(names)
1000
login_times = {i:names.count(i) for i in names}
for k, v in login_times.items():
print( k, v)
王五 119
李四 100
崔九 105
刘八 109
顾十 101
黄大 90
田七 100
张三 101
王二 100
赵六 75
min_value = min(login_times.values())
min_times = {i:names.count(i) for i in names if names.count(i) == min_value}
min_times
{'赵六': 75}
max_value = max(login_times.values())
max_times = {i:names.count(i) for i in names if names.count(i) == max_value}
max_times
{'王五': 119}
练习目标是熟悉字典的 values() 方法及其在众数等统计中的应用,以及使用 items() 方法遍历字典元素的技巧。同时将字典等容器类型的技巧与Excel读写结合起来,了解在实际工作中使用python的方法。
具体来说,本作业的主要思路如下:
登录次数统计与上节课的作业完全相同,只不过将读取文本文件改成 xlwings 读取Excel;另外打印在屏幕上时,可以使用
for k, v in d.items():
print(k, v)
形式的循环,从而简化代码;
统计登录最多的员工时,可以使用 max 与 values() 配合的方法;
统计登录最少的员工时,可以使用 min 与 values() 配合的方法。
参考答案:
import xlwings as xw
app = xw.App()
wb = app.books.open('d:/homework/python02_16_01.xlsx')
all_names = wb.sheets[0].range('c3:c1002').value
wb.close()
app.quit()
all_counts = { k : all_names.count(k) for k in all_names}
print('全部登录次数:')
for k,v in all_counts.items():
print( k , v )
print('登录最多人员:')
d_max = { k:v for k,v in all_counts.items() if v==max(all_counts.values())}
for k,v in d_max.items():
print( k, v)
print('登录最少人员:')
d_min = { k:v for k,v in all_counts.items() if v==min(all_counts.values())}
for k,v in d_min.items():
print( k, v)
练习2:解包操作练习
请在Python交互式窗口中完成以下操作:
创建一个列表 x = [ 1, 3, 5, 7, 9 ] ;
使用解包方法,将 x 列表中的五个元素分别赋值给 a、b、c、d、e 五个变量 ;
一共只使用一行代码、交换a与e、b与d的值,运行后 a=9、e=1、b=7、c=3 ;
重新赋值,执行 a,b,*c = x ,执行后观察a、b、c的结果,并思考原因;
创建一个字典 y = { 1:’One’, 3:’Three’, 5:’Five’, 7:’Seven’, 9:’Nine’ } ;
将字典中的所有键赋值给 a、b、c、d、e 五个变量,运行后 a=1、b=3、…… ;
将字典中的所有值赋值给 a、b、c、d、e 五个变量,运行后 a=’One’、b=’Three’、…… ;
执行 a,*b,c = y.items() , 然后观察 a、b、c 的结果,并思考原因。
x = [i for i in range(1, 10, 2)]
a, b, c, d, e = x
a, b, d, e = e, d, b, a
for i in (a, b, d, e):
print(i)
9
7
3
1
a, b, *c = x
a
1
b
3
c
[5, 7, 9]
y = {1:'One', 3:'Three', 5:'Five', 7:'Seven', 9:'Nine'}
a, b, c, d, e = y
y = {1:'One', 3:'Three', 5:'Five', 7:'Seven', 9:'Nine'}
a, b, c, d, e = y.values()
a,*b,c = y.items()
b
[(3, 'Three'), (5, 'Five'), (7, 'Seven')]