s14_day03_集合/文件操作/with/字符编码转换/函数/函数参数组/局部变量/高阶函数
'''
以色列,每年看书64本每人
中国人均4本
《追风》这本书讲的在阿富汉
探探算法,根据你的喜好来判断
推荐书
《追风筝的人》
《白鹿原》
《林达看美国〉
'''
当你混得不错的时候
一、字符串操作
特性:不可修改
字符串是不可以修改的,如果进行修改就变成了新的字符串
1).首字母大写
1 name = 'king' 2 print(id(name),name) #56320864 king 3 name1 = name.capitalize() #所有的字符串操作都会变成一个新的字符串 4 print(id(name1),name1) #首字母大写 57415232 King 5 print(id(name),name) #10904544 king
2).首字母大写
1 name = 'KING xiaofei' 2 names = name.casefold() #大写全部变小写 3 print(names) #king xiaofei
3).一个字符如果不够少位,然后用什么填充
1 name = 'a' 2 print(name.center(50,"-")) #字符串a 不够50个用-来填充 ,输出 ------------------------a-------------------------
4).统计字符出现的次数
1 name = 'king xiaofei xiaoxiao' 2 name_count = name.count('xiao') #统计 xiao出现次数 3 print(name_count) #3
5).将字符串转码,python中字符串都是ascii 码,而到了python中默认的所有字符串都是unicode编码
1 name = '小飞哥' 2 print(type(name)) #<class 'str'> 3 str_to_bytes = name.encode('utf-8') 4 print(str_to_bytes) #将字符串编码成bytes格式 #b'\xe5\xb0\x8f\xe9\xa3\x9e\xe5\x93\xa5' 5 # 再将字节的转换为字符串 6 print(str_to_bytes.decode('utf-8').encode('gb2312')) #将字符串utf-8转换为gb2312 7 print(name.encode('gb2312')) #直接转换 b'\xd0\xa1\xb7\xc9\xb8\xe7'
6).判断字符串是否以 Li结尾
1 name = 'king aaaLi' 2 ret = name.endswith("Li") 3 print(ret) #True
7).将字符串中带有tab的用多少个空格来替换
1 name = 'Alex\tli\txiexie' 2 # "Alex\tLi".expandtabs(10) #输出'Alex Li', 将\t转换成多长的空格 3 ret = name.expandtabs(10)# 将字符串中有\t的转换为10个空格的字符串 4 print(ret) #Alex li xiexie
8).查找字符在字符串中的位置,返回该字符串的索引,如果不存在返回-1
1 name = 'king xiaofei' 2 ret = name.find('n') 3 print(ret) #2 位置在下标2 4 print(name.find('d')) #-1 这个不存在
二. 字典操作
字典一种key - value 的数据类型,使用就像我们上学用的字典,通过笔划、字母来查对应页的详细内容。
定义一个字典
1 d = {'king':'xiaofei','xixi':'喜喜'} 2 print(d['king']) #xiaofei 椐据键值的方式来取值
字典的常用操作
1 d = {'king':'xiaofei','xixi':'喜喜'} 2 print(d.keys()) #dict_keys(['king', 'xixi']) 3 print(d.items()) #dict_items([('king', 'xiaofei'), ('xixi', '喜喜')]) 4 print(d.get('king')) #xiaofei 5 print(d.get('abc')) #None abc的键值不存在 6 # print(d['abc']) #KeyError: 'abc' 这个不存在
三. 集合操作
集合是一个无序的,不重复的数据组合,它的主要作用如下:
- 去重,把一个列表变成集合,就自动去重了
- 关系测试,测试两组数据之前的交集、差集、并集等关系
假定两个场景,两个班,一个LIUX,一个Python 需要计算是一共多少个人,但里面的人有部分的人是都报了名的假如两个班级需要统计出来两个班的人那些是报两个班的,需要统计出来
1).创建一个数值集合
第一种方式创建:
1 s = set([1,2,3,4,5]) 2 print(type(s),s) #<class 'set'> #{1, 2, 3, 4, 5}
第二种方式创建:
1 list_1 = [1, 4, 5, 7, 3, 6, 7, 9] 2 list_2 = set(list_1) 3 print(list_2, type(list_2)) 4 # {1, 3, 4, 5, 6, 7, 9} <class 'set'> 集合也是无序的
2).快速去重
交集
1 list_11 = set([1, 4, 55, 68, 99, 10, 4, 10]) 2 list_l2 = set([1, 2, 3, 5, 6, 7, 8, 9, 10]) 3 a = list_11.intersection(list_l2) 4 print(a) #{1, 10} 5 print(id(list_11), id(list_l2)) # 59442400 59443720 6 print(id(list_11), list_11) # 59442400 {1, 99, 4, 68, 10, 55} 7 print(id(a), a) # 59443000 {1, 10}
并集
1 list_11 = set([1, 4, 55, 68, 99, 10, 4, 10]) 2 list_l2 = set([1, 2, 3, 5, 6, 7, 8, 9, 10]) 3 b = list_11.union(list_l2) 4 print(b) 5 # {1, 2, 99, 4, 68, 3, 5, 6, 7, 10, 8, 9, 55}
差集,两组数据中没有的 in list_1 but not in list_2
1 c = list_11.difference(list_l2) 2 print(c) 3 # {99, 4, 55, 68} list_l1 里面有,list_l2里面没有的 4 5 print(list_l2.difference(list_11)) # {2, 3, 5, 6, 7, 8, 9}list_l2里面有的,list_l1里面没有的
子集
1 list_3 = set([1, 2, 3, 5, 9]) 2 list_4 = set([1, 2, 5]) 3 4 print(list_4.issubset(list_3)) # list_4 是不是list_3的子集 true
父集
1 list_3 = set([1, 2, 3, 5, 9]) 2 list_4 = set([1, 2, 5]) 3 # list_3是不是list_4的父集 4 print(list_3.issuperset(list_3)) # true
对称差集(反向差集),相两个里面都有的去掉,取两个里面的孤立的
1 list_1_name = set([1, 2, 3, 5, 9, 10, 11]) 2 list_2_name = set([2, 3, 5, 11]) 3 print(list_1_name.intersection(list_2_name)) 4 # {3, 2, 11, 5}
判断两个是不是没有交集
1 list1 = set([1, 3, 7]) 2 list2 = set([5, 6, 8]) 3 print(list1.isdisjoint(list2)) # True 4 5 list1 = set([1, 3, 5, 7]) 6 list2 = set([1, 3]) 7 print(list1.isdisjoint(list2)) # False 两个存在交集
上面的交集,并集,差集,除了用函数的方式调用,还可以通过符号的方式来
1 # 交集 2 list1 = set([1, 3, 5, 7, 9, 11, 22]) 3 list2 = set([0, 2, 66, 4, 77, 9, 22]) 4 5 print(list1 & list2) # {9, 22} 6 7 # 并集 8 # union 9 print(list1 | list2) # {0, 1, 2, 3, 66, 5, 4, 7, 9, 11, 77, 22} 10 11 # 差集 12 # difference 13 print(list1 - list2) # {1, 3, 5, 7, 11} 14 15 # 对称差集(反向差集),相两个里面都有的去掉,取两个里面的孤立的 16 # intersection 17 print(list1 ^ list2) # {0, 1, 2, 66, 4, 3, 5, 7, 11, 77}
集合中的增删改查
1、 集合的添加
1 t = set() #创建一个空集合 2 print(t, type(t), id(t)) # set() <class 'set'> 44567168 一个集合没有值的时候默认会显示类型 3 # 1)、添加一项 4 t.add('x') # 添加一项 5 print(t, type(t), id(t)) # {'x'} <class 'set'> 44567168 6 7 # 2)、添加多项 8 t.update([10, 2, 33, 55]) 9 print(t, type(t), id(t)) # {33, 2, 'x', 10, 55} <class 'set'> 44567168
2、集合的删除
1).使用remove()可以删除一项,如果被删除的对象不存在就会报错
1 # 使用remove()可以删除一项,如果被删除的对象不存在就会报错 2 t = set([1, 3, 5, 7, 9, 7]) 3 print(t) # {1, 3, 5, 7, 9} 集合的数据是不会重复的 4 t.remove(5) 5 print(t) # {1, 3, 7, 9}
2). discard
t = set([1, 3, 5, 7, 9, 7]) print(t.discard('f')) #删除元素f 但这个是不存在的,所以返回一个None
3).pop随机删
1 t = set([1, 3, 5, 7, 9, 7]) 2 print(t.pop()) # 1 被删除的对象是1 3 print(t.pop()) # 3 被删除的对象是3
4).查询长度
1 s = set([1,3,5,69,88,105]) 2 ret = len(s) 3 print(ret) #6s 4 # set 的长度
判断是不是在里面
# x in s # 测试 x 是否是 x 的成员 # x not in s # 测试 x 不是 s 的员成
s = set([1,3,5,69,88,105]) ret = 3 in s print(ret) #True print(66 not in s) #True
四. 文件操作
# 对文件的操作流程 # 1.打开,得到一个文件的句柄 # 2.操作 # 3.关闭文件
02_data_yesterday文件内容
1 Somehow, it seems the love I knew was always the most destructive kind 2 不知为何,我经历的爱情总是最具毁灭性的的那种 3 Yesterday when I was young 4 昨日当我年少轻狂 5 The taste of life was sweet 6 生命的滋味是甜的 7 As rain upon my tongue 8 就如舌尖上的雨露 9 I teased at life as if it were a foolish game 10 我戏弄生命 视其为愚蠢的游戏 11 The way the evening breeze 12 就如夜晚的微风 13 May tease the candle flame 14 逗弄蜡烛的火苗 15 The thousand dreams I dreamed 16 我曾千万次梦见 17 The splendid things I planned 18 那些我计划的绚丽蓝图 19 I always built to last on weak and shifting sand 20 但我总是将之建筑在易逝的流沙上 21 I lived by night and shunned the naked light of day 22 我夜夜笙歌 逃避白昼赤裸的阳光 23 And only now I see how the time ran away 24 事到如今我才看清岁月是如何匆匆流逝 25 Yesterday when I was young 26 昨日当我年少轻狂 27 So many lovely songs were waiting to be sung 28 有那么多甜美的曲儿等我歌唱 29 So many wild pleasures lay in store for me 30 有那么多肆意的快乐等我享受 31 And so much pain my eyes refused to see 32 还有那么多痛苦 我的双眼却视而不见 33 I ran so fast that time and youth at last ran out 34 我飞快地奔走 最终时光与青春消逝殆尽 35 I never stopped to think what life was all about 36 我从未停下脚步去思考生命的意义 37 And every conversation that I can now recall 38 如今回想起的所有对话 39 Concerned itself with me and nothing else at all 40 除了和我相关的 什么都记不得了 41 The game of love I played with arrogance and pride 42 我用自负和傲慢玩着爱情的游戏 43 And every flame I lit too quickly, quickly died 44 所有我点燃的火焰都熄灭得太快 45 The friends I made all somehow seemed to slip away 46 所有我交的朋友似乎都不知不觉地离开了 47 And only now I'm left alone to end the play, yeah 48 只剩我一个人在台上来结束这场闹剧 49 Oh, yesterday when I was young 50 噢 昨日当我年少轻狂 51 So many, many songs were waiting to be sung 52 有那么那么多甜美的曲儿等我歌唱 53 So many wild pleasures lay in store for me 54 有那么多肆意的快乐等我享受 55 And so much pain my eyes refused to see 56 还有那么多痛苦 我的双眼却视而不见 57 There are so many songs in me that won't be sung 58 我有太多歌曲永远不会被唱起 59 I feel the bitter taste of tears upon my tongue 60 我尝到了舌尖泪水的苦涩滋味 61 The time has come for me to pay for yesterday 62 终于到了付出代价的时间 为了昨日 63 When I was young 64 当我年少轻狂
1 data = open('02_data_yesterday').read() 2 # UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 106: illegal multibyte sequence 3 4 # 这个提示需要指定一个编码,操作系统是中文的,默认的是GBK的方式打开,但是python默认的文件格式是utf-8,所以会出错的
# 我们可以一部到位的读取文件里面的内容,但是我们打开了以后只是读了内容并没有关闭文件,这个还存在内存中的
# 指定打开文件的编码格式
# data = open('02_data_yesterday',encoding='utf-8').read()
# print(data)
上面的操作我们如果需要将文件打开以后还需要更多的操作就需要将打开的文件存起来,方便后面的操作
1 f = open('02_data_yesterday',encoding='utf-8') #打开一个文件以utf-8的编码格式读取,得到一个打开文件的句柄f 2 data1 = f.read() #读取文件里面所有的内容 3 data2 = f.read() #这里再次读取内容这里面没有数据了 4 5 print(data1) 6 print("*"*30) 7 print(data2) #这里没有数据 8 9 # 因为read()在读取的时候将内容全部读回来了 10 # 再读的话就读到文件最末尾再往后读就没有数据的了 11 # 在文件里同维护着一个文件指针的概念,每次打开就从最开始读
1 f = open("02_data_yesterday",'r',encoding='utf-8') 2 # 连续读3行数据 3 print(f.readline())#Somehow, it seems the love I knew was always the most destructive kind 4 print(f.readline())#不知为何,我经历的爱情总是最具毁灭性的的那种 5 print(f.readline())#Yesterday when I was young
上面的直接循环读3次效果是一样的
1 f = open("02_data_yesterday",'r',encoding='utf-8') 2 for i in range(3): 3 print(f.readline().strip())#读取一行,并去掉后面的换行与空格
radlines() 这个可以将内容读成一个列表格式
1 f = open("02_data_yesterday",'r',encoding='utf-8') 2 # print(f.readlines()) #这是将整个文件读成一个列表格式 3 4 # 假如我们第10条不需要打印出来如何做到? 5 for line in f.readlines(): 6 print(line.strip())
假如我们第10条不需要打印出来如何做到?
1 f = open("02_data_yesterday",'r',encoding='utf-8') 2 for index,line in enumerate(f.readlines()): 3 if index == 10: #如果index到10就跳过 4 continue 5 print(index,line.strip())
0 Somehow, it seems the love I knew was always the most destructive kind 1 不知为何,我经历的爱情总是最具毁灭性的的那种 2 Yesterday when I was young 3 昨日当我年少轻狂 4 The taste of life was sweet 5 生命的滋味是甜的 6 As rain upon my tongue 7 就如舌尖上的雨露 8 I teased at life as if it were a foolish game 9 我戏弄生命 视其为愚蠢的游戏 11 就如夜晚的微风 12 May tease the candle flame 13 逗弄蜡烛的火苗 14 The thousand dreams I dreamed 15 我曾千万次梦见 16 The splendid things I planned 17 那些我计划的绚丽蓝图 18 I always built to last on weak and shifting sand 19 但我总是将之建筑在易逝的流沙上 20 I lived by night and shunned the naked light of day 21 我夜夜笙歌 逃避白昼赤裸的阳光 22 And only now I see how the time ran away 23 事到如今我才看清岁月是如何匆匆流逝 24 Yesterday when I was young 25 昨日当我年少轻狂 26 So many lovely songs were waiting to be sung 27 有那么多甜美的曲儿等我歌唱 28 So many wild pleasures lay in store for me 29 有那么多肆意的快乐等我享受 30 And so much pain my eyes refused to see 31 还有那么多痛苦 我的双眼却视而不见 32 I ran so fast that time and youth at last ran out 33 我飞快地奔走 最终时光与青春消逝殆尽 34 I never stopped to think what life was all about 35 我从未停下脚步去思考生命的意义 36 And every conversation that I can now recall 37 如今回想起的所有对话 38 Concerned itself with me and nothing else at all 39 除了和我相关的 什么都记不得了 40 The game of love I played with arrogance and pride 41 我用自负和傲慢玩着爱情的游戏 42 And every flame I lit too quickly, quickly died 43 所有我点燃的火焰都熄灭得太快 44 The friends I made all somehow seemed to slip away 45 所有我交的朋友似乎都不知不觉地离开了 46 And only now I'm left alone to end the play, yeah 47 只剩我一个人在台上来结束这场闹剧 48 Oh, yesterday when I was young 49 噢 昨日当我年少轻狂 50 So many, many songs were waiting to be sung 51 有那么那么多甜美的曲儿等我歌唱 52 So many wild pleasures lay in store for me 53 有那么多肆意的快乐等我享受 54 And so much pain my eyes refused to see 55 还有那么多痛苦 我的双眼却视而不见 56 There are so many songs in me that won't be sung 57 我有太多歌曲永远不会被唱起 58 I feel the bitter taste of tears upon my tongue 59 我尝到了舌尖泪水的苦涩滋味 60 The time has come for me to pay for yesterday 61 终于到了付出代价的时间 为了昨日 62 When I was young 63 当我年少轻狂 [Finished in 0.2s]
假如一个文件有1G左右的话或者20G呢?实体机只有8G那就直接没办法运行了,如果用readlines()一次读进来直接死机了
我们就需要转变一种方式了,用高逼格的方式来实现!
# high bige ,这种方式内部实现的是一个迭代器的方式
1 f = open("02_data_yesterday",'r',encoding='utf-8') 2 # 这种方式是一行一行的读取的 3 count = 0 4 for line in f: #迭代器的方式读取 5 if count == 10: 6 count +=1 7 continue 8 print(count,line) 9 count+=1
0 Somehow, it seems the love I knew was always the most destructive kind 1 不知为何,我经历的爱情总是最具毁灭性的的那种 2 Yesterday when I was young 3 昨日当我年少轻狂 4 The taste of life was sweet 5 生命的滋味是甜的 6 As rain upon my tongue 7 就如舌尖上的雨露 8 I teased at life as if it were a foolish game 9 我戏弄生命 视其为愚蠢的游戏 11 就如夜晚的微风 12 May tease the candle flame 13 逗弄蜡烛的火苗 14 The thousand dreams I dreamed 15 我曾千万次梦见 16 The splendid things I planned 17 那些我计划的绚丽蓝图 18 I always built to last on weak and shifting sand 19 但我总是将之建筑在易逝的流沙上 20 I lived by night and shunned the naked light of day 21 我夜夜笙歌 逃避白昼赤裸的阳光 22 And only now I see how the time ran away 23 事到如今我才看清岁月是如何匆匆流逝 24 Yesterday when I was young 25 昨日当我年少轻狂 26 So many lovely songs were waiting to be sung 27 有那么多甜美的曲儿等我歌唱 28 So many wild pleasures lay in store for me 29 有那么多肆意的快乐等我享受 30 And so much pain my eyes refused to see 31 还有那么多痛苦 我的双眼却视而不见 32 I ran so fast that time and youth at last ran out 33 我飞快地奔走 最终时光与青春消逝殆尽 34 I never stopped to think what life was all about 35 我从未停下脚步去思考生命的意义 36 And every conversation that I can now recall 37 如今回想起的所有对话 38 Concerned itself with me and nothing else at all 39 除了和我相关的 什么都记不得了 40 The game of love I played with arrogance and pride 41 我用自负和傲慢玩着爱情的游戏 42 And every flame I lit too quickly, quickly died 43 所有我点燃的火焰都熄灭得太快 44 The friends I made all somehow seemed to slip away 45 所有我交的朋友似乎都不知不觉地离开了 46 And only now I'm left alone to end the play, yeah 47 只剩我一个人在台上来结束这场闹剧 48 Oh, yesterday when I was young 49 噢 昨日当我年少轻狂 50 So many, many songs were waiting to be sung 51 有那么那么多甜美的曲儿等我歌唱 52 So many wild pleasures lay in store for me 53 有那么多肆意的快乐等我享受 54 And so much pain my eyes refused to see 55 还有那么多痛苦 我的双眼却视而不见 56 There are so many songs in me that won't be sung 57 我有太多歌曲永远不会被唱起 58 I feel the bitter taste of tears upon my tongue 59 我尝到了舌尖泪水的苦涩滋味 60 The time has come for me to pay for yesterday 61 终于到了付出代价的时间 为了昨日 62 When I was young 63 当我年少轻狂 [Finished in 0.1s]
文件指针所在位置
1 f = open("02_data_yesterday",'r',encoding='utf-8') 2 print(f.tell()) # 0 当前指针所在位置 0代表当前文件指针位置在文件的最开始 3 # data = f.readline() #这里读取一行 4 data = f.read(71) #71这里指定要读取的位置长度为71 5 print(len(data),data) #读取一行,长度是71,指针指向下一个位置 6 print(f.tell()) #72 当前文件指针所在位置72 7 8 # seek()设置进去 9 f.seek(0)#设置回去的位置到文件的起始位置 10 print(f.tell()) # 0 当前位置为文件开始 11 print(f.readline()) #Somehow, it seems the love I knew was always the most destructive kind 12 13 14 15 # f.encoding 显示这个文件的编码格式 16 print(f.encoding) #utf-8 17 18 # f.buffer() 19 print(f.fileno()) #返回这个文件在内存的编号 #3 20 21 print(f.seekable())#不是所有的文件都有移回去的,这个是判断是不是两进制文件 22 print(f.tell()) #72 当前 23 24 print(f.readable())#判断文件是否可读 #True 25 26 print(f.writable())#判断是否可写 #False
f.flush() #刷新文件,如写一个文件,我们以为写进去了,但可能会出现还在内存里面但没有写进去,因为内存有一个缓存buffer,当满了以后才刷新到文件中,如果没有满就不刷新状态的
编写一个小实例,进度条程序
1 import sys 2 import time 3 4 for i in range(50): 5 sys.stdout.write('#') #写入#到显示器 6 sys.stdout.flush() #刷新缓存区 7 time.sleep(0.2) #每次等待0.2秒
f.close() #关闭文件
1 f = open('02_data_yesterday','r',encoding='utf-8') 2 f.readline() 3 f.close()
f.truncate() #截段文件,将文件截断成为指定的长度
1 # 文件里面内容写上:Somehow, it seems the love I knew was always the most destructive kind 2 f = open('02_data_yesterday_wb','a') #Somehow, it seems the love I knew was always the most destructive kind 3 f.truncate(10) #这个记得一定要能写入的方式打开,不然操作不了 打开文件的时候要吧用a的方式打开 4 #Somehow, i 这个是截取以后10个字符
文件打开的方式
# r+ 读写方式
1 f = open("02_data_yesterday",'r+',encoding='utf-8') #读写,是先读里面的内容,然后写到文件最后面 2 # f = open("02_data_yesterday",'w+',encoding='utf-8') #写读,先创建一个文件然后再写入去 3 # f = open("02_data_yesterday",'a+',encoding='utf-8') #追加读写,将写文件最后面 4 # f = open("02_data_yesterday",'rb') #以二进制只读的方式打开 5 print(f.readline()) 6 print(f.readline()) 7 print(f.readline()) 8 f.write("#####################") #这个将写在文件最后面 9 print(f.readline())
# 以二进制读写追加模式打开,这类的在网络传送的时候用到这种方式
1 f = open('02_data_yesterday','rb') #以只读的2进制方式打开 2 print(f.readline()) #b'Somehow, it seems the love I knew was always the most destructive kind\r\n'
以2进制写的方式打开
1 f = open("02_data_yesterday_wb",'wb') 2 # f.write("小飞哥") #TypeError: a bytes-like object is required, not 'str' 3 f.write("小飞哥".encode()) #转换为2进制,默认不写就是utf-8编码
写两个小实例,一个进度条,一个文件指针的移动
一、 进度条
1 import sys 2 import time 3 for i in range(50): #循环50次 4 sys.stdout.write('#') #写入#到显示器 5 sys.stdout.flush() #刷新缓存区 6 time.sleep(0.2) #每次等待0.2秒
二、一个文件指针的位置移动
1 f = open("02_data_yesterday",'r+',encoding='utf-8') 2 print(f.tell()) #0 当前位置是0 3 print(f.readline(),f.tell()) # 72 4 print(f.readline(),f.tell()) #140 5 print(f.readline(),f.tell()) #168 6 f.seek(0) #将文件指引移动到文件开始 0 7 print(f.readline(),f.tell()) #72
总结:文件加载,与文件的修改,所有文件的修改都是全新的存储,不可能局部的修改的
# 三、旅行者1号探测器,人的渺小地球的渺小
# 1.多看书,多看电影,多旅行让你的人生见识多了,产生文化冲突,会引法自己的思考
# 人的痛苦源于对自己无能的愤怒!!!
# 落日,西港的海滩
with 打开文件with可以自动关闭文件,不需要调用文件的f.close()
with语句的使用,with的作用是自动帮你关闭文件
# 1)、单个文件的打开
# with open('log1','rb') as file1 ,open('log2') as file2:
# pass
# python建议每一行的代码不要超过80个字符,长了可以用\分行写
1)、打开单个文件
1 with open('02_data_yesterday','r',encoding='utf-8') as f: 2 for line in f: 3 print(line.strip())
2)、打开多个文件,官方建议每一行python代码不要超过80个字符 长了可以用\分行
1 with open('02_data_yesterday','rb') as file1 ,\ 2 open('02_data_yesterday_wb','rb') as file2: 3 print(file1.readline(),file2.readline())
五. 字符编码与转码
先说python2
- py2里默认编码是ascii
- 文件开头那个编码声明是告诉解释这个代码的程序 以什么编码格式 把这段代码读入到内存,因为到了内存里,这段代码其实是以bytes二进制格式存的,不过即使是2进制流,也可以按不同的编码格式转成2进制流,你懂么?
- 如果在文件头声明了#_*_coding:utf-8*_,就可以写中文了, 不声明的话,python在处理这段代码时按ascii,显然会出错, 加了这个声明后,里面的代码就全是utf-8格式了
- 在有#_*_coding:utf-8*_的情况下,你在声明变量如果写成name=u"大保健",那这个字符就是unicode格式,不加这个u,那你声明的字符串就是utf-8格式
- utf-8 to gbk怎么转,utf8先decode成unicode,再encode成gbk
再说python3
- py3里默认文件编码就是utf-8,所以可以直接写中文,也不需要文件头声明编码了,干的漂亮
- 你声明的变量默认是unicode编码,不是utf-8, 因为默认即是unicode了(不像在py2里,你想直接声明成unicode还得在变量前加个u), 此时你想转成gbk的话,直接your_str.encode("gbk")即可以
- 但py3里,你在your_str.encode("gbk")时,感觉好像还加了一个动作,就是就是encode的数据变成了bytes里,我擦,这是怎么个情况,因为在py3里,str and bytes做了明确的区分,你可以理解为bytes就是2进制流,你会说,我看到的不是010101这样的2进制呀, 那是因为python为了让你能对数据进行操作而在内存级别又帮你做了一层封装,否则让你直接看到一堆2进制,你能看出哪个字符对应哪段2进制么?什么?自己换算,得了吧,你连超过2位数的数字加减运算都费劲,还还是省省心吧。
- 那你说,在py2里好像也有bytes呀,是的,不过py2里的bytes只是对str做了个别名(python2里的str就是bytes, py3里的str是unicode),没有像py3一样给你显示的多出来一层封装,但其实其内部还是封装了的。 这么讲吧, 无论是2还是三, 从硬盘到内存,数据格式都是 010101二进制到-->b'\xe4\xbd\xa0\xe5\xa5\xbd' bytes类型-->按照指定编码转成你能看懂的文字
编码应用比较多的场景应该是爬虫了,互联网上很多网站用的编码格式很杂,虽然整体趋向都变成utf-8,但现在还是很杂,所以爬网页时就需要你进行各种编码的转换,不过生活正在变美好,期待一个不需要转码的世界。
最后,编码is a piece of fucking shit, noboby likes it.
python3默认是unicode(万国码)编码,如果需要将字符编码的转换就应该先将所有的编码转换为中间的unicode然后再转成自己想要的编码格式
# 每个国家都有自己的编码格式,所以就出来了unicode,这个所有的字符都是存两个字符
# utf-8 可变长的字符编码,所有的英文占一个字节,但是所有的中文是3个字节
# 编码的原则记得一定要先将所有的当前编码转换为unicode,然后再通过已转的unicode转换为自己想要的编码格式
1 #-*- coding:utf-8 -*- 2 s = "你好" 3 s_to_gbk = s.encode('gbk') 4 print(s_to_gbk) #b'\xc4\xe3\xba\xc3'
打印当前系统的默认编码格式
1 import sys 2 print(sys.getdefaultencoding()) #utf-8
python3中的来回转换编码
1 s = "你好" #python中默认是unicode 2 # s_to_gbk = s.decode("utf-8").encode('gbk') #告诉这个s是utf-8 的编码,转成unicode,然后再转成gbk 3 s_to_unicode = s.decode('utf-8')#告诉系统将上面的s转换为unicode,他的编码是utf-8,不写就是系统编码 4 print(s_to_unicode,type(s_to_unicode))
python3中,所有的变量字符串这些都是 Unicode编码,就算是设置了也只是文件的编码,但内部默认还是Unicode编码的
1 s = "你好" #这个在python3默认就是Unicode的编码 2 print(s.encode('gbk')) #b'\xc4\xe3\xba\xc3' 3 s_utf8 = s.encode("utf-8") 4 print(s_utf8) #b'\xe4\xbd\xa0\xe5\xa5\xbd' 5 print(s_utf8.decode('utf-8').encode("gb2312")) #b'\xc4\xe3\xba\xc3' 6 # 这句话的意思是告诉当前是utf-8的编码转成gb2312
python2小练习
1 #-*-coding:gb2312 -*- #这个也可以去掉 2 # 练习,在python2里面将所有的gb2312转换为utf-8,然后再将gb2312转换为gbk 3 4 # 打印当前系统的默认编码格式 5 # import sys 6 # print(sys.getdefaultencoding()) #pytnon 2 中默认是 ascii 7 8 import sys 9 print(sys.getdefaultencoding()) #pytnon 2 中默认是 ascii 10 11 msg = "我爱北京天安门" 12 #msg_gb2312 = msg.decode("utf-8").encode("gb2312") 13 msg_gb2312 = msg.encode("gb2312") #默认就是unicode,不用再decode,喜大普奔 14 gb2312_to_unicode = msg_gb2312.decode("gb2312") 15 gb2312_to_utf8 = msg_gb2312.decode("gb2312").encode("utf-8") 16 17 print(msg) 18 print(msg_gb2312) 19 print(gb2312_to_unicode) 20 print(gb2312_to_utf8)
六. 函数
函数是什么?
函数一词来源于数学,但编程中的「函数」概念,与数学中的函数是有很大不同的,具体区别,我们后面会讲,编程中的函数在英文中也有很多不同的叫法。在BASIC中叫做subroutine(子过程或子程序),在Pascal中叫做procedure(过程)和function,在C中只有function,在Java里面叫做method。
定义: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可
特性:
- 减少重复代码
- 使程序变的可扩展
- 使程序变得易维护
语法定义
定义一个函数
1 def func1(): 2 '''第一个函数testing1''' 3 print('int the func1') 4 return 0
定义了一个过程,没有返回值的函数,所以叫一个过程
1 def func2(): 2 '''testing 2''' 3 print("in the func2")
函数的返回,可以返回多个值
def func3(): '''testing 3''' print("int the func3") return 1,"hello",['name','name2'],{'age',30}
调用上面的三个函数
1 x = func1() #int the func1 2 y = func2() #in ther func2 3 z = func3() 4 print(x) #返回的是0 5 print(y) #返回的是None 过程 6 print(z) #(1, 'hello', ['name', 'name2'], {'age', 30}) 返回的是一个元组
总结:
返回值数=0:返回的是None
返回值数=1:返回的是一个Object
返回值数>1:返回的是tuple
为什么要有返回值?
根据执行结果来执行不同的操作
2.函数参数与局部变量
带参数的函数
1 def test(x,y): #这里的x,y是形参 2 print(x) 3 print(y) 4 5 # test() #TypeError: test() missing 2 required positional arguments: 'x' and 'y' 6 # 调用函数的时候缺少参数 7 8 test(2,3) #这里传入的是实参 9 #实参与形参是完全一一对应的
默认参数
1 def test(x,y=2): #这里的x,y默认值是2 2 print(x) 3 print(y) 4 5 # test() #TypeError: test() missing 2 required positional arguments: 'x' and 'y' 6 # 缺少参数 7 8 test(2,3) #2 3 这里传入的是实参,传入的时候可以少传入一个 9 test(333) #333 2 10 # 默认参数,可以省略带有默认值的参数
指定关键字的方式传入参数,与位置调用方式
1 def test(x,y): 2 print(x) 3 print(y) 4 5 test(y=30,x=20)# 关键字方式调用,与形参顺序无关,指定名字的方式传入参数 20 ,30 还是这样子传入的 6 7 x = 1 8 y = 2 9 test(x=x,y=y) #注意这里是两种不同的方式,后面的是实参。前面的形参 1,2
1.形参和实参:
形参:形式参数,不是实际存在,是虚拟变量。在定义函数和函数体的时候使用形参,目的是函数调用时接收实参(实参个数,类型就与实参一一对应)
实参:实际参数,调用函数时传给函数的参数,可以是变量,表达式,函数,传给形参
区别:形参是虚拟的,不占用空间,形参变量只有在被调用时才分配内存单元,实参是一个变量,占用内存空间,数据传送单向,不参形参传给实参
2.位置参数和关键字(标准调用,实参与形参位置一一对应,关键字调用:位置无需固定)
3.默认参数,可以省略带有默认值的参数
默认参数的特点:调用函数的时候,默认参数非必须传递
参数组:若你的函数在定义时不确定用户想传入多少个参数,就可以使用非固定参数
可变长度的参数
1 # *args接收N个元组参数 2 def test1(*args): 3 print(args) 4 test1(1,2,3,3,5) #传入的是一个元组 (1, 2, 3, 3, 5) 5 test1(*[1,2,3,45,66]) #args = tuple(1, 2, 3, 45, 66)
可变长度的参数,可以与实参合用
1 def test2(x,*args): 2 print(x) 3 print(args) 4 5 test2(1,2,3,4,5,6,68) #1 (2, 3, 4, 5, 6, 68)
把关键字参数以字典的方式传入,个数都是可变长度
1 # **kwargs:接受N个关键字参数,转换成字典的方式 2 def test_dict(**kwargs): 3 print(kwargs) 4 5 6 test_dict(name="king",age=30) #{'name': 'king', 'age': 30} 7 8 9 # 如果是传入字典的模式,就需要写两个** 10 d = {'name': 'king', 'age': 30} 11 test_dict(**d) #{'name': 'king', 'age': 30}
可变长度参数与默认参数/必填参数的实例
def test(name,age=18,**kwargs): print(name) print(age) print(kwargs) test('king',sex='m',hoboy='tesla') test('king',sex='m',hoboy='tesla',age=3) #这样子也以的 test('king',3,sex='m',hoboy='tesla') #这样子也以的,3可以理解为以位置方式传值 # king # 18 # {'sex': 'm', 'hoboy': 'tesla'}
1 def test(name,age=18,*args,**kwargs): 2 print(name) 3 print(args) 4 print(age) 5 print(kwargs) 6 7 test('king',age=34,sex='m',hoboy='tesla') 8 9 # king 10 # () 11 # 34 12 # {'sex': 'm', 'hoboy': 'tesla'}
七. 局部变量
1)。定义一个可以修改名字的程序
1 def change_name(name): 2 print('before change %s'%name,id(name)) 3 name = 'xiaofei' #这个就是一个局部变量,只在函数内部生效,不会影响外面变量,这个函数就是这个变量的作用域 4 print(id(name),name) 5 6 name = 'king' 7 print(id(name),name) #59663200 king 8 9 change_name(name) 10 # before change king 59663200 11 # 59663328 xiaofei 12 13 print(id(name),name) #59663200 king 说明没有修改到? 14 15 # 局部变量与全局变量 16 # 局部变量,只在作用域内生效,如上面的只在函数体内生效 17 # 全局变量:这个是一级变量,放在文件的顶部,或者说一级,顶格变量
2).在局部变量中就是需要修改全局变量怎么样做
1 name = 'xiaofei' #全局变量 2 3 def change_name(arg): 4 global name #声明这个是全局变量 5 name = arg 6 7 print(id(name),name) 8 change_name('king') 9 print(id(name),name) #king
3).在局部变量里面声明全局变量
1 def change_name(arg): 2 global name #声明这个是全局变量,全局里面如果没有就自动创建,有的话就拿过来 3 name = arg 4 5 change_name('king') 6 print(id(name),name) #king
注意:在函数里面不应该修改全局变量,函数里面声明全局变量更加不建议这样子用
4).局部变量是可以修改字典,列表,集合,类里面的数据的
1 names = ['king','xiaofei',{"age":30,"address":'广东'}] 2 def change_name(): 3 names[0]='xiaoking' #修改列表的数据 4 names[2]['age'] = 40 #修改字典里面的数据 5 6 print(id(names),names) #11855952 ['king', 'xiaofei', {'age': 30, 'address': '广东'}] 7 change_name() 8 print(id(names),names) #11855952 ['xiaoking', 'xiaofei', {'age': 30, 'address': '广东'}]
上面局部变量可以修改引用的数据类型,除了字符串与数字不能修改,其它引用的类型,都可以修改
八. 递归
python的递归最大是999层
1 def calc(n): 2 print(n) 3 return calc(n+1) 4 5 6 # calc(0) #RecursionError: maximum recursion depth exceeded while calling a Python object
写一个程序一直除以2,直到除不近的时候退出
1 def calc(n): 2 print(n) 3 if int(n/2) >0: 4 return calc(int(n/2)) 5 print("--->",n) 6 7 calc(10) 8 # 10 9 # 5 10 # 2 11 # 1 12 # ---> 1
九. 高阶函数
变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
1 def add(a,b,fun): 2 return fun(a)+fun(b) 3 4 # abs 这个是绝对值,可以将负数转换为正数 5 res = add(3,-6,abs) 6 print(res) #9
# http://www.cnblogs.com/alex3714/articles/5717620.html
作业:程序练习
程序1:实现简单的shell sed 替换功能
data_db
1 Somehow, it seems the love I knew was always the most destructive kind 2 不知为何,我经历的爱情总是最具毁灭性的的那种 3 Yesterday when I was young 4 昨日当我年少轻狂 5 The taste of life was sweet 6 生命的滋味是甜的 7 As rain upon my tongue 8 就如舌尖上的雨露 9 I teased at life as if it were a foolish game 10 我戏弄生命 视其为愚蠢的游戏 11 The way the evening breeze 12 就如夜晚的微风 13 May tease the candle flame 14 逗弄蜡烛的火苗 15 The thousand dreams I dreamed 16 我曾千万次梦见 17 The splendid things I planned 18 那些我计划的绚丽蓝图 19 I always built to last on weak and shifting sand 20 但我总是将之建筑在易逝的流沙上 21 I lived by night and shunned the naked light of day 22 我夜夜笙歌 逃避白昼赤裸的阳光 23 And only now I see how the time ran away 24 事到如今我才看清岁月是如何匆匆流逝 25 Yesterday when I was young 26 昨日当我年少轻狂 27 So many lovely songs were waiting to be sung 28 有那么多甜美的曲儿等我歌唱 29 So many wild pleasures lay in store for me 30 有那么多肆意的快乐等我享受 31 And so much pain my eyes refused to see 32 还有那么多痛苦 我的双眼却视而不见 33 I ran so fast that time and youth at last ran out 34 我飞快地奔走 最终时光与青春消逝殆尽 35 I never stopped to think what life was all about 36 我从未停下脚步去思考生命的意义 37 And every conversation that I can now recall 38 如今回想起的所有对话 39 Concerned itself with me and nothing else at all 40 除了和我相关的 什么都记不得了 41 The game of love I played with arrogance and pride 42 我用自负和傲慢玩着爱情的游戏 43 And every flame I lit too quickly, quickly died 44 所有我点燃的火焰都熄灭得太快 45 The friends I made all somehow seemed to slip away 46 所有我交的朋友似乎都不知不觉地离开了 47 And only now I'm left alone to end the play, yeah 48 只剩我一个人在台上来结束这场闹剧 49 Oh, yesterday when I was young 50 噢 昨日当我年少轻狂 51 So many, many songs were waiting to be sung 52 有那么那么多甜美的曲儿等我歌唱 53 So many wild pleasures lay in store for me 54 有那么多肆意的快乐等我享受 55 And so much pain my eyes refused to see 56 还有那么多痛苦 我的双眼却视而不见 57 There are so many songs in me that won't be sung 58 我有太多歌曲永远不会被唱起 59 I feel the bitter taste of tears upon my tongue 60 我尝到了舌尖泪水的苦涩滋味 61 The time has come for me to pay for yesterday 62 终于到了付出代价的时间 为了昨日 63 When I was young 64 当我年少轻狂
python代码部分
1 ''' 2 python3 执行这个程序 3 格式 python 文件名 查找的字符串 替换的字符串 4 5 ''' 6 import sys 7 import os 8 print(len(sys.argv),sys.argv) 9 10 # 输入的参数必须等于3,不然就格式不对 11 if len(sys.argv) == 3: 12 old_str = sys.argv[1] #查找的字符串 13 new_str = sys.argv[2] #被替换的字符串 14 else: 15 print("缺少参数!!!\n格式:python 文件名.py 查找字符串 替换字符串") 16 exit() 17 18 19 with open('data_db','r',encoding='utf-8') as old_file ,open('data_bk_db','w',encoding='utf-8') as new_file: 20 for line in old_file: 21 line = line.replace(old_str,new_str) 22 new_file.write(line) 23 24 25 # 替换完了以后修改文件名 26 os.rename('data_db','data_db_bak') 27 os.rename('data_bk_db','data_db') 28 os.rename('data_db_bak','data_bk_db') 29 30 # shell命令 31 # F:\Design\git\gitlab\python\oldpythons14\s3\student_class>python 01_实现简单的shell替换功能.py 年少轻狂 **年少轻狂** 32 # 3 ['01_实现简单的shell替换功能.py', '年少轻狂', '**年少轻狂**']
# 程序2:修改haproxy配置文件
1 global 2 log 127.0.0.1 local2 3 daemon 4 maxconn 256 5 log 127.0.0.1 local2 info 6 defaults 7 log global 8 mode http 9 timeout connect 5000ms 10 timeout client 50000ms 11 timeout server 50000ms 12 option dontlognull 13 14 listen stats :8888 15 stats enable 16 stats uri /admin 17 stats auth admin:1234 18 19 frontend oldboy.org 20 bind 0.0.0.0:80 21 option httplog 22 option httpclose 23 option forwardfor 24 use_backend www.oldboy.org if www 25 26 27 28 backend www.qq.com 29 server 192.168.100.102 192.168.100.102 weight 20 maxconn 30
# 实现增删改查的功能
# eval()可以将字符串转换为字典
1 # 1、查 2 # 输入:www.qq.com 3 # 获取当前backend下的所有记录 4 5 # 2、新建 6 # 输入: 7 # arg = { 8 # 'bakend': 'www.qq.com', 9 # 'record':{ 10 # 'server': '100.1.7.9', 11 # 'weight': 20, 12 # 'maxconn': 30 13 # } 14 # } 15 16 # 3、删除 17 # 输入: 18 # arg = { 19 # 'bakend': 'www.oldboy.com', 20 # 'record':{ 21 # 'server': '100.1.7.9', 22 # 'weight': 20, 23 # 'maxconn': 30 24 # } 25 # } 26 27 def count_host(fileAllPath='haproxy_db'): 28 ''' 29 统计里面的文件所在的行数 30 :param fileAllPath: 31 :return:返回一个字典 格式 {27: 'www.oldboy.org', 30: 'www.163.com'} 32 ''' 33 hosts = {} 34 f = open(fileAllPath, 'r', encoding='utf-8') 35 data = f.readlines() 36 for n, line in enumerate(data): 37 if line.find('backend') != -1 and line.find('use_backend') == -1: 38 hosts[n] = line.replace('backend', '').strip() 39 f.close() 40 return hosts 41 42 43 def host(bakend, server, weight=20, maxconn=30): 44 arg = { 45 'bakend': bakend, 46 'record': { 47 'server': server, 48 'weight': weight, 49 'maxconn': maxconn 50 } 51 } 52 return arg 53 54 55 def addBackend(databases): 56 # 请输入相关的信息 57 inp_bakend = input("请输入网址:") 58 inp_server = input("请输入服务器IP:") 59 d = host(bakend=inp_bakend, server=inp_server) 60 # print(d) 61 # print('bakend\t{bakend}\n\t\tserver {server} 100.1.7.9 weight 20 maxconn 3000' % (bakend = d['bakend'], server = 62 # d['record']['server'])) 63 string = ''' 64 backend {backend} 65 server {server} {server} weight {weight} maxconn {maxconn}'''.format(backend=d['bakend'], 66 server=d['record']['server'], 67 weight=d['record']['weight'], 68 maxconn=d['record']['maxconn']) 69 # print(string) 70 with open(databases, 'a', encoding='utf-8') as f: 71 ret = findDomain(databases, d['bakend']) 72 # print(ret) 73 if not ret[0]: 74 print("操作成功!!!") 75 f.write(string) 76 else: 77 print("域名已存在跳过!!!") 78 79 80 def getMenu(): 81 menu = {1: "查找", 2: "添加", 3: "修改", 4: "删除"} 82 print('请选择需要操作的菜单序号!') 83 for x in menu: 84 print(x, menu[x]) 85 return menu 86 87 88 def findDomain(databases, inp_domain): 89 # inp_domain = input("请输入要查询的域名") 90 hosts = count_host(databases) 91 # print(inp_domain in hosts.values(),hosts) 92 return inp_domain in hosts.values(), hosts, inp_domain 93 94 95 def getDomain(databases): 96 host = count_host(databases) 97 for i in host: 98 print(i, host[i]) 99 inp_delDomain = input("请输入的域名序号:") 100 return inp_delDomain 101 102 103 def delBackend(databases): 104 ret = getDomain(databases) 105 ret = int(ret) 106 # 正式删除配置信息 107 bak_database = databases + '_bk' 108 # print(old_database) 109 old_file = open(databases, 'r', encoding='utf-8') 110 new_file = open(bak_database, 'w', encoding='utf-8') 111 for n, line in enumerate(old_file.readlines()): 112 if n == ret or n == ret + 1: 113 continue 114 new_file.write(line) 115 new_file.close() 116 old_file.close() 117 118 # 修改文件配置,重命名文件 119 os.remove(databases) 120 os.rename(bak_database, databases) 121 122 def changeBackend(databases): 123 ret = getDomain(databases) 124 ret = int(ret) 125 # 正式删除配置信息 126 bak_database = databases + '_bk' 127 old_file = open(databases, 'r', encoding='utf-8') 128 new_file = open(bak_database, 'w', encoding='utf-8') 129 for n, line in enumerate(old_file.readlines()): 130 if n == ret or n == ret + 1: 131 continue 132 new_file.write(line) 133 new_file.close() 134 old_file.close() 135 136 # 修改文件配置,重命名文件 137 os.remove(databases) 138 os.rename(bak_database, databases) 139 140 addBackend(databases) 141 142 import sys 143 import time 144 import os 145 146 databases = 'haproxy_db' 147 148 falg = True 149 while falg: 150 menu_n = getMenu() 151 inp_menu = input("请选择你要输入的序号:") 152 if inp_menu.isdigit(): 153 inp_menu = int(inp_menu) 154 if inp_menu > 0 and inp_menu <= len(menu_n): 155 # print("序号合法!!!") 156 if inp_menu == 1: 157 # print("查询!!!") 158 inp_domain = input("请输入要查询的域名") 159 ret = findDomain(databases, inp_domain) 160 if ret[0]: 161 print('%s域名存在!!!' % ret[2]) 162 print('\t所有域名列表:') 163 for line in ret[1].values(): 164 print('\t\t', line) 165 break 166 else: 167 print("\t域名不存在\n所有的域名列表如下!!") 168 for line in ret[1].values(): 169 print('\t\t', line) 170 elif inp_menu == 2: 171 print("添加!") 172 addBackend(databases) 173 elif inp_menu == 3: 174 print("修改") 175 changeBackend(databases) 176 else: 177 print('删除') 178 delBackend(databases) 179 else: 180 print("输入不合法!!!") 181 elif inp_menu == 'q': 182 sys.stdout.write("正在退出系统!!!") 183 for i in range(15): 184 sys.stdout.write("$") 185 sys.stdout.flush() 186 time.sleep(0.05) 187 falg = False 188 else: 189 print("你的输入有误!!!")

浙公网安备 33010602011771号