遍历字典元素:values、keys、items

使用 for i in d:的方式遍历字典,i每次都是d中元素(键值对)的键,而不包括值。

字典的 values() 方法及应用

字典对象 values 方法:将该字典中所有元素(键值对)的值放入可迭代对象,从而可用for循环逐个读取。

values 方法返回的可迭代对象:

Python2中返回一个列表 Python3中是可迭代对象,不支持索引,也不支持next() Python3中返回的对象属于dictview()类型

二阶频次统计

  1. a = ['张三','李四','张三','王五','张三','李四','张三','王五','王五','张三','赵六','赵六']
  2. d = {i:a.count(i) for i in a}
  3. d
  1. {'张三': 5, '李四': 2, '王五': 3, '赵六': 2}

如何使用字典统计以下信息:
出现5次者1人
出现2次者2人
出现3次者1人

image.png

  1. for i in d:
  2. print(i)
  1. 张三
  2. 李四
  3. 王五
  4. 赵六
  1. for i in d.values():
  2. print(i)
  1. 5
  2. 2
  3. 3
  4. 2
  1. for i in d:
  2. print(d[i])
  1. 5
  2. 2
  3. 3
  4. 2
  1. new_d = {i:list(d.values()).count(i) for i in d.values()}
  2. new_d
  1. {5: 1, 2: 2, 3: 1}

对于可迭代对象a:
list(a)根据a生成一个新的列表对象
tuple(a)根据a生成一个新的元组对象
set(a)根据a生成一个新的集合对象
dict(a)根据a生成一个新的字典对象

求取列表的“众数”——出现次数最多的那个元素

计算步骤

  1. 先算出每个元素的出现次数,存入字典d
  2. 用max函数算出d的所有值即 d.values() 中,最大数值是几
  3. 创建一个新字典,将d中符合条件的元素、即“值”等于“最大次数”的元素添加进来
  1. a = ['A','B','A','C','B','C','B','B','C','D','C','D','E']
  2. d = {i:a.count(i) for i in a}
  3. maxv = max(d.values())
  4. new_d = {i:d[i] for i in d if d[i] == maxv}
  5. new_d
  1. {'B': 4, 'C': 4}

字典的 keys() 和 items() 方法

字典对象的 keys() 方法与 values() 分相似,不过返回的是所有的键。
字典对象的 items() 方法也返回一个 dictview,其中每个元素都是一个元组,包含字典中的一对键和值,比如 (‘A’, 2)。

  1. for i in d.keys():
  2. print(i)
  1. A
  2. B
  3. C
  4. D
  5. E
  1. for i in d.items():
  2. print(i)
  3. print(i[0], i[1])
  1. ('A', 2)
  2. A 2
  3. ('B', 4)
  4. B 4
  5. ('C', 4)
  6. C 4
  7. ('D', 2)
  8. D 2
  9. ('E', 1)
  10. E 1

更简洁地使用 items()

  1. for k, v in d.items()
  2. # k 被赋值为键
  3. # v 被赋值为值
  1. for x, y in d.items():
  2. print(x, y)
  1. A 2
  2. B 4
  3. C 4
  4. D 2
  5. E 1

反向索引字典

  1. d = {y:x for x, y in d.items()}
  2. d
  1. {2: 'D', 4: 'C', 1: 'E'}
  1. d = {'张三':'091','李四':'092','王五':'087','赵六':'085'}
  2. new_d = {y:x for x, y in d.items()}
  3. new_d
  1. {'091': '张三', '092': '李四', '087': '王五', '085': '赵六'}

解包

解包.png
列表、元组、集合的解包:将等号左侧变量分别赋值为每个元素
字符串解包:将等号左侧变量分别赋值为每个字符
字典解包:将等号左侧变量分别赋值为每个键,没有值

  1. d.items()
  1. dict_items([('张三', '091'), ('李四', '092'), ('王五', '087'), ('赵六', '085')])
  1. a, b, c = '甲乙丙'
  1. a
  1. '甲'
  1. b
  1. '乙'
  1. c
  1. '丙'

解包的特殊形式:多元赋值

同时将多个值赋给多个变量,即“多元赋值语句”。常被用于交换变量数值

  1. a, b = 1, 2
  1. a
  1. 1
  1. b
  1. 2
  1. a = 3
  2. b = 4
  3. a, b = b, a # 相当于 a, b = 4, 3,自动解包并赋值
  1. a
  1. 4
  1. b
  1. 3

如果需要将元组、列表、字典、集合等容器中的元素取出来、并分别赋值给多个变量,只需在容器前标注星号,然后放到能够赋值的代码结构(比如赋值语句、for循环、调用函数时的参数值)中即可。比如:

  1. a,b,c = [*(2, 5, 7)]
  2. x = some_function( [*a_list] )
  1. a, b, c = (2, 5, 7)
  1. a
  1. 2
  1. b
  1. 5
  1. a,b,c = [*(3, 4, 5)]
  1. a
  1. 3
  1. b
  1. 4
  1. a_list = (2, 5, 7)
  2. x = sum([*a_list])
  3. x
  1. 14
  1. a_list = (2, 5, 7)
  2. x = sum(a_list)
  3. x
  1. 14
  1. a,*b,*c = (1,2,3,4,5)
  1. File "<ipython-input-68-cb60fc6d6f2b>", line 4
  2. SyntaxError: two starred expressions in assignment

上式由于存在多种分配方案(即“歧义”),实际运行无法通过。

如果等号左侧变量数目多于右侧解包出来的元素个数,会导致程序错误。
如果等号左侧变量数目少于右侧解包出来的元素个数, Python2 中会导致程序错误;而 Python3 中则允许通过星号的方式正确赋值。

星号

星号的含义:将剩余内容放入列表,赋值给变量 星号可以加在任意变量前面 分配的规则:先处理位置明确的变量,然后再将剩余内容作为列表赋值给对应变量

【注意事项】 1.即使只剩一个元素,也会放入列表 2.如果剩余元素无法明确分配给多星号变量,则提示出错

  1. 打分 = [7.8,7.2,8.3,7.2,8.5,8.2,8.5,7.9]
  2. 最高分,*有效分,最低分 = sorted(打分)
  3. 有效分
  1. [7.2, 7.8, 7.9, 8.2, 8.3, 8.5]
  1. 最高分
  1. 7.2
  1. 最低分
  1. 8.5

练习

练习1:字典汇总统计

首先下载 某企业ERP系统登录日志 工作簿文件。

请编写一个程序,使用 print 在屏幕上输出以下统计指标:

每位员工的登录次数;

登录次数最多的员工及其登录次数;

登录次数最少的员工及其登录次数。

  1. import xlwings as xw
  2. app = xw.App()
  3. workbook = app.books.open('python02_16_01.xlsx')
  4. worksheet = workbook.sheets[0]
  5. worksheet
  1. <Sheet [python02_16_01.xlsx]登录日志>
  1. start_row = 3
  2. end_row = 1003
  3. names = []
  4. for row in range(start_row, end_row):
  5. row = str(row)
  6. name = worksheet.range('C' + row).value
  7. names.append(name)
  8. workbook.close()
  9. app.quit()
  1. len(names)
  1. 1000
  1. login_times = {i:names.count(i) for i in names}
  1. for k, v in login_times.items():
  2. print( k, v)
  1. 王五 119
  2. 李四 100
  3. 崔九 105
  4. 刘八 109
  5. 顾十 101
  6. 黄大 90
  7. 田七 100
  8. 张三 101
  9. 王二 100
  10. 赵六 75
  1. min_value = min(login_times.values())
  2. min_times = {i:names.count(i) for i in names if names.count(i) == min_value}
  3. min_times
  1. {'赵六': 75}
  1. max_value = max(login_times.values())
  2. max_times = {i:names.count(i) for i in names if names.count(i) == max_value}
  3. max_times
  1. {'王五': 119}

练习目标是熟悉字典的 values() 方法及其在众数等统计中的应用,以及使用 items() 方法遍历字典元素的技巧。同时将字典等容器类型的技巧与Excel读写结合起来,了解在实际工作中使用python的方法。

具体来说,本作业的主要思路如下:

登录次数统计与上节课的作业完全相同,只不过将读取文本文件改成 xlwings 读取Excel;另外打印在屏幕上时,可以使用

  1. for k, v in d.items():
  2. print(k, v)

形式的循环,从而简化代码;

统计登录最多的员工时,可以使用 max 与 values() 配合的方法;

统计登录最少的员工时,可以使用 min 与 values() 配合的方法。

参考答案:

  1. import xlwings as xw
  2. app = xw.App()
  3. wb = app.books.open('d:/homework/python02_16_01.xlsx')
  4. all_names = wb.sheets[0].range('c3:c1002').value
  5. wb.close()
  6. app.quit()
  7. all_counts = { k : all_names.count(k) for k in all_names}
  8. print('全部登录次数:')
  9. for k,v in all_counts.items():
  10. print( k , v )
  11. print('登录最多人员:')
  12. d_max = { k:v for k,v in all_counts.items() if v==max(all_counts.values())}
  13. for k,v in d_max.items():
  14. print( k, v)
  15. print('登录最少人员:')
  16. d_min = { k:v for k,v in all_counts.items() if v==min(all_counts.values())}
  17. for k,v in d_min.items():
  18. 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 的结果,并思考原因。

  1. x = [i for i in range(1, 10, 2)]
  2. a, b, c, d, e = x
  1. a, b, d, e = e, d, b, a
  1. for i in (a, b, d, e):
  2. print(i)
  1. 9
  2. 7
  3. 3
  4. 1
  1. a, b, *c = x
  1. a
  1. 1
  1. b
  1. 3
  1. c
  1. [5, 7, 9]
  1. y = {1:'One', 3:'Three', 5:'Five', 7:'Seven', 9:'Nine'}
  2. a, b, c, d, e = y
  1. y = {1:'One', 3:'Three', 5:'Five', 7:'Seven', 9:'Nine'}
  2. a, b, c, d, e = y.values()
  1. a,*b,c = y.items()
  1. b
  1. [(3, 'Three'), (5, 'Five'), (7, 'Seven')]