全民一起玩Python提高篇第六课:深入容器类型(下)

集合类型

交集运算 &

>>> a={'A','B'}
>>> b={'B','C'}
>>> c=a & b
print(c)
{'B'}
d={'1'}
a={'A'}
c=a & d
print(c)
set()

得到的空集合是set(),因为直接一对花括号是字典

并集 |

c=a|d
c
{'A', '1'}

差集 -

>>> c=a-d
c
{'A'}

题目一:出勤统计

该文件的“考勤统计”工作表中,B、C、D 三列分别记录了三周的出勤记录。因为每周有5天,所以一个员工在一周内可能出勤多次。
请编写程序,使用print输出以下统计结果:
第一周出过勤,但第二周完全缺勤的人员名单(即第二周从未出现过该名字)
第二周出过勤,但第一周完全缺勤的人员名单
从第一周到第三周全都出过勤、从未缺勤的人员名单
第一周和第二周全都出过勤、但第三周完全缺勤的人员名单
从第一周到第三周,所有曾经出勤(即使只在一周出过勤)的人员总名单
完成之后,请改写程序,将结果直接写入Excel工作表(自行指定行列位置)。

import xlwings as xw
app=xw.App()
wb=app.books.open('E:\拷贝过来的文件\全民一起玩Python\MyProject\Test1\提高篇第十七课\讨论出勤情况.xlsx')
ws=wb.sheets['考勤统计']
d1,d2,d3=ws.range('B3:D30').value
d2=ws.range('C3:C30').value
d3=ws.range('D3:D30').value
#读入数据
ws.range('G2').options(transpose=True).value=list(set(d1)-set(d2))
#转置一下
ws.range('H2').options(transpose=True).value=list(set(d2)-set(d1))
ws.range('I2').options(transpose=True).value=list(set(d1) & set(d2) & set(d3))
ws.range('J2').options(transpose=True).value=list((set(d1) & set(d2)) - set(d3))
ws.range('K2').options(transpose=True).value=list((set(d1) | set(d2)) | set(d3))
wb.save()
wb.close()
app.quit()

题目二:Counter对象

利用Counter实现数据汇总统计

import  xlwings as xw
from collections import Counter
app=xw.App()
wb=app.books.open('E:\拷贝过来的文件\全民一起玩Python\MyProject\Test1\提高篇第十七课\年级录取情况统计.xlsx')
ws=wb.sheets['985']
Schools=ws.range('B2:B170').value
Count=Counter(Schools)
#调用COunter统计
ws.range('F2').options(transpose=True).value=list(Count.keys())
ws.range('G2').options(transpose=True).value=list(Count.values())
#返回的Counter是个特殊的字典
wb.save()
wb.close()
app.quit()
print(Count)

Counter比普通字典特殊的一点是,还可以做交集并集等运算

from collections import Counter
大一=['英语','高数','C语言','线性代数']
大二=['英语','高数','数据结构']
print(Counter(大一)+Counter(大二))
print(Counter(大一)-Counter(大二))
Counter({'英语': 2, '高数': 2, 'C语言': 1, '线性代数': 1, '数据结构': 1})
Counter({'C语言': 1, '线性代数': 1})

二维列表转为一维

from itertools import chain
a=[[1,5],[2,3],[5,2]]
x=list(chain(*a))
#连接一个个子列表,解包操作
print(max(x))

但如果列表套列表,就解不出了

题目三:利用字典统计出勤

统计第一周每个人的出勤次数,以字典形式打印在屏幕上;
统计刘八在第一周、第二周和第三周分别出勤几次,把三个数字打印在屏幕上;
统计每个人在三周里的总出勤次数,即每周出勤次数之和;
统计第三周比第二周出勤更多的人员名单,比如刘八在第三周出勤5次,而在第二周只出勤2次,所以应当显示在屏幕上。
直接从这个二维列表中得到每个人的三周总出勤次数(即第一周、第二周和第三周出勤次数之和)

import  xlwings as xw
from collections import Counter
app=xw.App()
wb=app.books.open('E:\拷贝过来的文件\全民一起玩Python\MyProject\Test1\提高篇第十七课\讨论出勤情况.xlsx')
ws=wb.sheets['考勤统计']
第一周=ws.range('B3:B30').value
第二周=ws.range('C3:C30').value
第三周=ws.range('D3:D30').value
a=ws.range('B3:D30').value
wb.close()
app.quit()
print(Counter(第一周))
print(Counter(第一周)['刘八'],Counter(第二周)['刘八'],Counter(第三周)['刘八'])
print(Counter(第一周)+Counter(第二周)+Counter(第三周))
print(Counter(第三周)-Counter(第二周))
print(Counter(chain(*a)))
Counter({'田七': 5, '崔九': 4, '王二': 3, '张三': 3, '王五': 3, '黄大': 3, '李四': 3, '刘八': 2, '顾十': 2})
2 2 4
Counter({'田七': 12, '王二': 9, '黄大': 9, '李四': 9, '刘八': 8, '崔九': 8, '顾十': 8, '赵六': 8, '张三': 7, '王五': 5, None: 1})
Counter({'崔九': 4, '顾十': 2, '刘八': 2, '王五': 2, None: 1})
Counter({'田七': 12, '王二': 9, '黄大': 9, '李四': 9, '赵六': 8, '刘八': 8, '崔九': 8, '顾十': 8, '张三': 7, '王五': 5, None: 1})

容器使用常见问题

默认参数问题

如果为自定义函数的参数指定默认值,那么该默认值最好不要使用可变类型对象(列表、字典、集合等)。如果使用了可变类型,每次调用该函数时,使用的默认值都是内存中的同一地址的同一个对象。这就意味着:每次调用函数时如果修改了这个默认值参数,则该修改将一直保留在内存中,下一次调用该函数时会继续受到影响。

def add_END(t=[]):
    t.append('END')
    return t

if __name__=="__main__":
    x=add_END()
    print(x)
    y = add_END()
    print(y)
    z = add_END()
    print(z)
['END']
['END', 'END']
['END', 'END', 'END']

深拷贝和浅拷贝

浅拷贝

>>> a=['A','B','C']
>>> b=a
>>> b
['A', 'B', 'C']
>>> b[0]='甲'
>>> b
['甲', 'B', 'C']
>>> a
['甲', 'B', 'C']

两个列表相当于指针,修改了一个,另一个也会变化
当然这里可以使用切片赋值

a=[1,2,3]
b=a[:]
b
[1, 2, 3]
a.append(4)
b
[1, 2, 3]
c=a
c
[1, 2, 3, 4]
a.append(2)
a
[1, 2, 3, 4, 2]
c
[1, 2, 3, 4, 2]

用copy的话可以实现浅拷贝,看起来确实相当于两个列表了

>>> a=['A','B']
>>> b=a.copy()
>>> b
['A', 'B']
>>> b[0]='甲'
>>> b
['甲', 'B']
>>> a
['A', 'B']

但是当列表嵌套列表时,只能管到其中一层。嵌套的列表传的也是地址。

>>> a=['A','B',['C','D']]
>>> b=a.copy()
>>> b[2][0]='乙'
>>> a
['A', 'B', ['乙', 'D']]

深拷贝

>>> from copy import deepcopy
>>> b=deepcopy(a)
>>> a
['A', 'B', ['乙', 'D']]
>>> b
['A', 'B', ['乙', 'D']]
>>> b[2][1]='甲'
>>> a
['A', 'B', ['乙', 'D']]
>>> b
['A', 'B', ['乙', '甲']]

误用乘法制作二维列表

>>> a=[0]*3
>>> a
[0, 0, 0]
>>> b=[a]*2
>>> b
[[0, 0, 0], [0, 0, 0]]
>>> b[0][1]=111
>>> b
[[0, 111, 0], [0, 111, 0]]

b的第一项和第二项指向的是同一个地址,列表乘法执行的是浅拷贝

>>> b=[[0]*3 for _ in range(2)]
# 没有实意就不用i,用下划线就好
>>> b
[[0, 0, 0], [0, 0, 0]]

Numpy和Pandas

Numpy

>>> x=[10,20,38,230,21]
>>> import numpy as np
>>> a=np.array(x)
# 转为ndarray类的数组
>>> a
array([ 10,  20,  38, 230,  21])
#ndarray进行矩阵运算
>>> b=a*3
>>> b
array([ 30,  60, 114, 690,  63])
>>> c=np.array(range(5))
>>> d=b-c
>>> d
array([ 30,  59, 112, 687,  59])
>>> d=d.tolist()
>>> d
[30, 59, 112, 687, 59]
#转换为普通列表

np自带很多函数

>>> a
array([ 10,  20,  38, 230,  21])
>>> np.max(a)
230
>>> np.mean(a)
63.8
>>> np.median(a)
21.0
#中位数

转为2X3的矩阵

>>> x=[1,2,3,4,5,6]
>>> a=np.array(x)
>>> b=a.reshape(2,3)
>>> b
array([[1, 2, 3],
       [4, 5, 6]])

矩阵转置

>>> b.T
array([[1, 4],
       [2, 5],
       [3, 6]])

pandas

pandas=panel data
pandas读写Excel需要事先安装两个包
xlrd和openpyxl

import pandas as pd
工资=pd.read_excel('E:\拷贝过来的文件\全民一起玩Python\MyProject\Test1\提高篇第十九课\工资统计.xlsx')
#读写结果只有一维,就是series,如果多行多列,就是dataframe
print(工资)
工资数据=工资.iloc[4:,3:]
#截取数据
print(工资数据)
工资数据.to_excel('E:\拷贝过来的文件\全民一起玩Python\MyProject\Test1\提高篇第十九课\工资统计.xlsx','Sheet1')
#写入一个新的Excel才行,直接写入源文件会覆盖掉
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值