python第二周day4(9.26)
1、字典和集合作业更改版
# 已知变量orders中保存一个店家的所有订单数据,每个订单包含:订单ID、用户ID、订单金额、支付金额、订单来源渠道、是否退货
orders = [
{'orderID': '254118088', 'userID': '157213', 'goodsID': 'PR000064', 'orderAmount': '272.51', 'payment': '272.51 ', 'chanelID': None, 'chargeback': False},
{'orderID': '263312190', 'userID': '191121', 'goodsID': 'PR000583', 'orderAmount': '337.93', 'payment': '337.93 ', 'chanelID': '渠道-0765', 'chargeback': True},
{'orderID': '188208169', 'userID': '211918', 'goodsID': 'PR000082', 'orderAmount': '905.68', 'payment': '891.23 ', 'chanelID': '渠道-0530', 'chargeback': False},
{'orderID': '203314910', 'userID': '201322', 'goodsID': 'PR000302', 'orderAmount': '786.27', 'payment': '688.88 ', 'chanelID': None, 'chargeback': False},
{'orderID': '283989279', 'userID': '120872', 'goodsID': 'PR000290', 'orderAmount': '550.77', 'payment': '542.51 ', 'chanelID': '渠道-9527', 'chargeback': False},
{'orderID': '279103297', 'userID': '146548', 'goodsID': 'PR000564', 'orderAmount': '425.2', 'payment': '425.20 ', 'chanelID': '渠道-0765', 'chargeback': False},
{'orderID': '316686066', 'userID': '148994', 'goodsID': 'PR000709', 'orderAmount': '1764.37', 'payment': '1707.04 ', 'chanelID': '渠道-0396', 'chargeback': False},
{'orderID': '306447069', 'userID': '104863', 'goodsID': 'PR000499', 'orderAmount': '499.41', 'payment': '480.42 ', 'chanelID': '渠道-0007', 'chargeback': False},
{'orderID': '290267674', 'userID': '206155', 'goodsID': 'PR000253', 'orderAmount': '1103', 'payment': '1050.95 ', 'chanelID': '渠道-0330', 'chargeback': False},
{'orderID': '337079027', 'userID': '211918', 'goodsID': 'PR000768', 'orderAmount': '465.41', 'payment': '465.41 ', 'chanelID': '渠道-9527', 'chargeback': False},
{'orderID': '417411381', 'userID': '148994', 'goodsID': 'PR000483', 'orderAmount': '279.53', 'payment': '279.53 ', 'chanelID': '渠道-0007', 'chargeback': False},
{'orderID': '254286596', 'userID': '174586', 'goodsID': 'PR000322', 'orderAmount': '622.7', 'payment': '622.70 ', 'chanelID': '渠道-0283', 'chargeback': False},
{'orderID': '303647260', 'userID': '178023', 'goodsID': 'PR000685', 'orderAmount': '969.61', 'payment': '913.58 ', 'chanelID': '渠道-0765', 'chargeback': False},
{'orderID': '347419495', 'userID': '209896', 'goodsID': 'PR000483', 'orderAmount': '279.18', 'payment': '225.15 ', 'chanelID': '渠道-0396', 'chargeback': False},
{'orderID': '384544993', 'userID': '148994', 'goodsID': 'PR000004', 'orderAmount': '3424.78', 'payment': '3424.78 ', 'chanelID': '渠道-0530', 'chargeback': False},
{'orderID': '322802617', 'userID': '125220', 'goodsID': 'PR000812', 'orderAmount': '430.69', 'payment': '4223.48 ', 'chanelID': '渠道-0530', 'chargeback': False},
{'orderID': '399101394', 'userID': '183645', 'goodsID': 'PR000025', 'orderAmount': '703.39', 'payment': '553.37 ', 'chanelID': '渠道-9527', 'chargeback': False},
{'orderID': '274413321', 'userID': '162256', 'goodsID': 'PR000813', 'orderAmount': '227.42', 'payment': '200.37 ', 'chanelID': '渠道-0530', 'chargeback': False},
{'orderID': '362677803', 'userID': '217238', 'goodsID': 'PR000400', 'orderAmount': '169.04', 'payment': '106.99 ', 'chanelID': '渠道-0789', 'chargeback': True}
]
# 1.(数据清洗)删除orders中支付金额大于订单金额的订单
# 提前将金额转换成浮点数
# for order in orders:
# order['payment'] = float(order['payment'])
# order['orderAmount'] = float(order['orderAmount'])
# print(orders)
# 方法一:提取,列表推导式(自己手动转类型)
# 提取有效数据,产生一个新的列表
# new_orders = [order for order in orders if float(order['payment']) <= float(order['orderAmount'])]
# 删除原来的数据
# del orders
# orders = new_orders
# print(new_orders) # 代码中查找 ctrl+f (有两个列表)
# **方法二(直接删掉不合理的数据,这个比较好一点)(考虑remove删不干净注意加[:])
for order in orders[:]: # 考虑remove删不干净注意加[:] 问题[:]的意思
# 获取支付金额和订单金额并且转换成浮点数
payment = float(order['payment']) # 先保存转换类型
orderAmount = float(order['orderAmount'])
# 删除支付金额 > 订单金额的订单
if payment > orderAmount:
orders.remove(order) # 删除数据
continue # 如果满足则删除,并取下一个值不用转换类型,不满足则转换类型
# 修改没有删删除的金额的类型
order['payment'] = payment
order['orderAmount'] = orderAmount
print(orders)
# 2.计算这个店家的总订单金额和总支付金额以及**实际销售额(店家真正拿到手中钱)(支付金额减去退货的金额)
sum1 = sum2 = sum3 = 0
for order in orders:
sum1 += order['orderAmount']
sum2 += order['payment']
if not order['chargeback']: # False # 可以写成 if order['chargeback'] == False
sum3 += order['payment']
print('总订单金额:', sum1)
print('总支付金额:', sum2)
print('实际销售额:', sum3) # 总订单金额: 13786.2
# 总支付金额: 13188.550000000001
# 实际销售额: 12743.630000000001
# **3.统计这个店家的订单的订单来源渠道的数量 (推导式来做,列表转换为集合去重)
chanels1 = [order['chanelID'] for order in orders if order['chanelID']] # 去掉None的渠道
chanels2 = set(chanels1)
print('来源渠道的数量:', len(chanels2)) # 来源渠道的数量: 8
# *4)计算订单退货率
# total = len(orders)
chargeback_count = total = 0
for order in orders:
total += 1
if order['chargeback']: #** True
chargeback_count += 1
print('退货率:', chargeback_count / total) # 退货率: 0.1111111111111111
# ****5) 获取最优广告渠道(哪个渠道订单多)
# 统计每个渠道产生的订单数
chanels2 = list(chanels2)
# 获取每个渠道的数量
chanels_count = []
for chanel in chanels2:
count = 0
for order in orders:
if order['chanelID'] == chanel:
count += 1
chanels_count.append(count)
# print(chanels2) #['渠道-0789', '渠道-0007', '渠道-0283', '渠道-9527', '渠道-0396', '渠道-0765', '渠道-0530', '渠道-0330']
# print(chanels_count) #[1, 2, 1, 3, 2, 3, 3, 1]
# 获取数量的最大值
max_count = max(chanels_count)
# 获取数量和最大值相等的渠道
best = []
for index in range(len(chanels_count)):
if chanels_count[index] == max_count:
best.append(chanels2[index])
print('最优渠道:', best) # 最优渠道: ['渠道-9527', '渠道-0765', '渠道-0530']
# 6)将订单渠道为None的订单的渠道值修改成最优广告渠道
for order in orders:
if not order['chanelID']: #** None-false -加not为True 相当于if x['chanelID'] == None:
order['chanelID'] = best[0]
print(orders)
# 7)在每个订单数据中添加一个键值对保存订单的折扣值
for order in orders:
order['discount'] = order['payment']/order['orderAmount'] #也可以用字典.setdefault ,因为原本就没有折扣
print(orders)
2、字符和字符串
1.什么是字符串(str)
“”"
- 字符串是容器型数据类型;
将’’,"",’’’’’’,""""""作为容器的标志,里面直接是多个符号,每个符号就是字符串 的每一个元素:‘元素1元素2元素3…’- 字符串不可变(不能增加删除改);字符串是有序的(支持下标操作和列表一样)
3) 元素 - 所有的符号都可以作为字符串的元素;字符串中的每个元素又叫字符。字符分为普通字符和转义字符两种。
“”"
1)字符串的元素(字符)可以是任意符号
‘abc’ ->'ABC’产生一个新的字符串
str1 = 'a啊,-=1~~^-^微(*^_^*)'
print(str1)
2)空字符串 # 里面什么都没有
str2 = ''
str3 = ""
str4 = ''''''
str5 = """"""
print(type(str4), len(str4),type(str5), len(str5)) # <class 'str'> 0 <class 'str'> 0
def func():
"""
文档注释
:return:
"""
3)多行字符串 ‘‘和"“不可以换行。”"""""和’’’’’'可以换行;两两之间没有区别
str1 = 'abc'
str2 = """123
abc
===
"""
print(str2)
str3 = 'abc\n123' # 借助\n进行换行
print(str3)
4)字符串是有序(顺序影响结果)
print('abc' == 'bca') # False
2.字符串中的元素 - 字符
- 普通字符 - 符号在字符串中表示符号本身的字符就是普通字符
2)转义字符 - 在特定符号前加\表示特殊功能或者特殊意义的字符
\n - 换行
\t - 水平制表符(相当于tab键,空格)
\’ - 表示一个普通的单引号
\" - 表示一个普通的双引号
\ - 表示一个普通的反斜杆
“”"\u4四位的16进制数 - 编码字符(四位的16进制数是字符的编码值
str0 = '123nabc'
str1 = '\t123\nabc'
print(str0, str1, sep='\n') # 123nabc 123 abc
str2 = 'It\'s OK' # 三个‘有歧义
print(str2) # abc
str3 = "It's ok" # (没有歧义)
str4 = "I say :\" good \" " # I say :" good "
str5 = 'I say :"good" '
print(str4)
str5 = 'C:User\\name\小明'
print(str5)
str6 = '\u4e00abc'
print(str6) # 一abc
3.字符编码
“”"
- 计算机在存储数据的时候只能存数字(数字的二进制补码)
2)为了能够让计算机存储字符,给每个字符对应了一个固定的数字。每次在存储这个字符的时候就存储这个字符对应的数字。
每个字符对应的数字就是这个字符的编码值。
‘a’ - 97
“”"
4.编码表 - 记录字符和数字对应关系的表
“”"
常用的编码表:ASCII码表,Unicode编码表(Python)
1)ASCII码表 - 128个符号:( 中0~9连续增加,数字在大写字母在小写字母前面,中间有特殊符号。)
a. 只记录了美国的符号(这里没有记录中文)
b. 数字字符(09)在大写字母的前面,大写字母(AZ)在小写字母(a~z)的前面。并且这三类符号之间不连续。
2)Unicode编码表:
a.是ASCII码表的扩展(包含了ASCII码表),记录了世界上所有的国家所有的民族的所有语言的符号(6万多个)
https://baike.baidu.com/item/%E7%BB%9F%E4%B8%80%E7%A0%81/2985798?fromtitle=Unicode&fromid=750500&fr=aladdin
b.中文范围:4e00~9fa5
“”"
5.编码值的使用
1)chr函数
chr(编码值) - 获取编码值对应的字符
print(chr(97)) # a -对应的编码值97 十进制
print(chr(0x5fa5)) # 徥 注意16进制的转换
# 练习:打印所有的中文
#num = 0
#for x in range(0x4e00, 0x9fa5+1):
# # num += 1
# print(chr(x), end=' ')
# # if num == 30:
# # print()
# # num = 0
# for y in range(0x2800, 0x28ff+1): # 盲文
# print(chr(y), end = ' ')
2)ord函数
ord(字符) - 获取字符编码值 (符号在计算机里面的数字)
print(ord('陈'), ord('来')) # 38472 26469
3)编码字符
\u四位的16进制编码值 a->97->0x61 a的十进制和十六进制
print('a\u0061') # aa
c = '是'
if '\u4e00'<= c <= '\u9fa5':
print('中文')
print('\u9fa5')
if '一' <= c <= '龥':
print('中文')
3、进制
0.十进制
基数:0~9
表示方式:直接写
转换函数:print()
num = 23490
print(num) # 23490
1.二进制
基数:0,1
表示方式:加前缀 0b/0B
转换函数:bin(数据) 英文字母的前三位
num = 0b101
print(num) # 5
2.八进制
基数:0~7
表示方式:加前缀 0O/0o
转换函数:oct(数据)
num = 0o23
print(num) # 19
3.十六进制
基数:09,af(A~F)
表示方式:加前缀 0x/0X
转换函数:hex(数据)
num = 0xa2
print(num) # 162
print(hex(100)) # 0x64 100转换为16进制数0x64
print(bin(100)) # 0b1100100
print(oct(100)) # 0o144
4、字符串相关操作和相关函数
1.查 - 获取字符
字符串获取字符和列表获取元素的语法一样
注意:一个转义字符的长度是1
str1 = 'how are you? i am fine ! thank you ! and you?'
print(str1[2], str1[-1]) # w ?
str1 = '\tabc\n123\u4e00'
print(str1[1], str1[-2]) # a 3
print(str1)
# 自己来输出答案 #有的最后一个取不到,注意方向,和间隔以及取到那个字符
print('===================')
print(str1[1:6]) # abc换行1 -->'abc\n1'
print(str1[-1:2]) # 空 -->''
print(str1[1:7:2]) # ac1 -->'ac1'
print(str1[-1::-2]) # 一2换行btab -->'一2\nb\t'
print(str1[2:]) # bc换行123一 -->'bc\n123一'
print('--------------------------------')
for x in str1:
print(x)
2.+,*
print('abc'+'hello') # abchello
print('abc'*3) # abcabcabc
print('===\n'*3)
3.比较运算
“”"
- 两个字符串比较大小,比较的是第一对儿不相等字符的编码值的大小
- 两个字符比较大小,比较的是字符的编码值的大小
已知字符X:
判断是否是数学字符: ‘0’ <= X <= ‘9’
判断是否是小写字母:‘a’ <= x <= ‘z’
判断是否是大写字母:‘A’ <= x <= ‘Z’
判断是否是字母:‘a’ <= x <= ‘z’ or ‘A’ <= x <= ‘Z’
判断是否是中文:’\u4e00’ <= x <= ‘\u9fa5’
“”"
print('abc' == 'acb') # False
print('abc' > 'Abc123') #比较编码值的大小 # True 数字字符(0~9)在大写字母的前面,大写字母(A~Z)在小写字母(a~z)的前面。并且这三类符号之间不连续。
print('你好' > 'hello') # True hello在ASCII码表中,< 中文在Unicode编码表
# 练习:已知一个字符串,统计字符串中中文出现的次数
str1 = '-==sh是uM09K你好!'
count = 0
for x in str1:
if '\u4e00' <= x <= '\u9fa5':
count += 1
print('中文出现的次数:', count) # 3
# *练习2:判断指定字符串是否是纯数字字符串
# '234445' -> 是 '122h2333' -> 不是
# 自己做的方法
str2 = '234445'
count = ''
count1 = ''
for x in str2:
if '0' <= x <= '9':
count += x
else:
count1 += x
if len(count) == len(str2):
print('234445是纯数字字符吗:', '是')
else:
print('234445是纯数字字符吗:', '不是')
str3 = '122h2333'
count = ''
count1 = ''
for x in str3:
if '0' <= x <= '9':
count += x
else:
count1 += x
if len(count) == len(str3):
print('122h2333是纯数字字符吗:', '是')
else:
print('122h2333是纯数字字符吗:', '不是')
# ***teacher 的方法
str2 = '234445'
str3 = '122h2333'
for x in str2:
if not '0' <= x <= '9':
print('不是纯数字字符串')
break
else:
print('是纯数字字符串')
# **练习3: 提取字符串中所有的大写字母
# '-==sh是uM09K你好!' -> 'MK'
str4 = '-==sh是uM09K你好!'
new_str4 = ''
for x in str4:
if 'A' <= x <= 'Z':
new_str4 += x
print(new_str4)
- in和 not in
字符串1 in 字符串2 - 判断字符串1是否是字符串2的子串(一部分)
print(10 in [10, 20, 30]) # True
print([10, 20] in [10, 20, 30]) # False
print('a' in 'abc123') # True
print('abc' in 'abc123') # True
print('ac' in 'abc123') # False
print('c1' in 'abc123') # True
5.相关函数
1)len(字符串) 转义字符长度是1
2)str(数据) - 将数据转换成字符串(任何类型的数据都可以转换成字符串;转换的时候直接在数据的打印值外面加引号)
x = 23
str(23) # '23'
str(12.5) # '12.5'
str(True) # 'True'
str([10,20]) # '[10, 20]'
str({'a': 10, "b": 20}) # "{'a': 10, 'b': 20}"-->打印值外面加双引号
print({'a': 10, "b": 20}) # {'a': 10, 'b': 20}
# str 菜鸟教程 字符串的内建函数