zoukankan      html  css  js  c++  java
  • Python学习-03(集合,文件,编码)

    上周复习:

    列表增删改查  元祖是可读列表

    字符串操作

    字典是无序的,通过key来找值。字典可以嵌套列表和字典

     

    本周内容:集合--文件---字符编码 

    集合引入:

    #随机生成20个小于20的数,输出所有的数,
    # 要求重复的输出一次
    1 import random
    2 a=[]
    3 for i in range(20):
    4     a.append(random.randint(1,20))
    5 for i in a:
    6     if i not in b:
    7         b.append(i)
    8 print(b)
    方法一:利用列表实现
    1 import random
    2 a=[]
    3 for i in range(20):
    4     a.append(random.randint(1,20))
    5 print(a)
    6 b=list(set(a))
    7 print(b)
    方法二:利用集合实现

    一、集合

    集合:非常简单的去重复。关系测试,不同列表的中的元素的关系。

    集合和字典一样是无序的。

    集合用的符号是{},和字典一样。

    集合:只能存储不可修改的数据(数值,字符串,元祖), 不能存储可以修改的数据类型(列表,字典,集合)

    1)集合的创建     set方法:可以把列表换成集合。

    1 list_1 = [1,4,5,7,3,6,7,9]
    2 list_1 = set(list_1)
    3 
    4 list_2 =set([2,6,0,66,22,8,4])
    5 
    6 print(list_1,list_2)
    集合创建

    2)集合的关系

    交集、并集、差集、子集、父集、对称差集

    交集:两个集合都拥有的公共部分

    并集:两个集合都拥有的所有部分

    差集:一个集合用户而另外一个集合没有的

    子集:集合A的所有元素都在集合B中,集合A称为集合B的子集,集合B称为集合A的父集。

    对称差集:两个集合的并集减去两个集合的交集。

     1 list_1 = [1,4,5,7,3,6,7,9]
     2 list_1 = set(list_1)
     3 
     4 list_2 =set([2,6,0,66,22,8,4])
     5 print(list_1,list_2)
     6 
     7 #交集
     8 print(  list_1.intersection(list_2) )
     9 
    10 #并集
    11 print(list_1.union(list_2))
    12 
    13 #差集 in list_1 but not in list_2
    14 print(list_1.difference(list_2))
    15 print(list_2.difference(list_1))
    16 
    17 #子集
    18 list_3 = set([1,3,7])
    19 print(list_3.issubset(list_1))
    20 print(list_1.issuperset(list_3))
    21 
    22 #对称差集
    23 print(list_1.symmetric_difference(list_2))
    24 
    25 print("-------------")
    26 
    27 list_4 = set([5,6,7,8])
    28 print(list_3.isdisjoint(list_4)) # Return True if two sets have a null intersection.
    29 
    30 #交集
    31 print(list_1 & list_2)
    32 #并集
    33 print(list_2 | list_1)
    34 #差集
    35 print(list_1 - list_2) # in list 1 but not in list 2
    36 #对称差集
    37 print(list_1 ^ list_2)
    集合的关系

    3)集合的操作

    增加 add():添加一项

    添加update():添加多项

    删除pop()随机删除一项

    删除remove():删除,如果不存在,报错

    删除discard():直接删除,没有返回值

    求长度,len()

    判断存在 x in s  

    判断不存在 x not in s

     1 list_1 = [1,4,5,7,3,6,7,9]
     2 list_1 = set(list_1)
     3 list_1.add(999)
     4 list_1.update([888,777,555])
     5 print(list_1)
     6 print(list_1.pop())
     7 print(  list_1.discard(888)  )
     8 print(len(list_1))
     9 print( '1' in  list_1)
    10 
    11 结果:
    12 {1, 3, 4, 5, 6, 7, 999, 9, 777, 555, 888}
    13 1
    14 None
    15 9
    16 False
    集合的操作

    二、字符编码

    decode 解码      encode  编码

    先说python2 

      1)py2里默认编码是ascii

      2)文件开头那个编码声明是告诉解释这个代码的程序 以什么编码格式 把这段代码读入到内存,因为到了内存里,这段代码其实是以bytes二进制格式存的,不过即使是2进制流,也可以按不同的编码格式转成2进制流,你懂么?

      3)如果在文件头声明了#_*_coding:utf-8*_,就可以写中文了, 不声明的话,python在处理这段代码时按ascii,显然会出错, 加了这个声明后,里面的代码就全是utf-8格式了。

      4)在有#_*_coding:utf-8*_的情况下,你在声明变量如果写成name=u"大保健",那这个字符就是unicode格式,不加这个u,那你声明的字符串就是utf-8格式。

      5)utf-8 to gbk怎么转,utf8先decode成unicode,再encode成gbk

    再说python3 

      1)py3里默认文件编码就是utf-8,所以可以直接写中文,也不需要文件头声明编码了,干的漂亮

      2)你声明的变量默认是unicode编码,不是utf-8, 因为默认即是unicode了(不像在py2里,你想直接声明成unicode还得在变量前加个u), 此时你想转成gbk的话,直接your_str.encode("gbk")即可以

      3)但py3里,你在your_str.encode("gbk")时,感觉好像还加了一个动作,就是就是encode的数据变成了bytes里,我擦,这是怎么个情况,因为在py3里,str and bytes做了明确的区分,你可以理解为bytes就是2进制流,你会说,我看到的不是010101这样的2进制呀, 那是因为python为了让你能对数据进行操作而在内存级别又帮你做了一层封装,否则让你直接看到一堆2进制,你能看出哪个字符对应哪段2进制么?什么?自己换算,得了吧,你连超过2位数的数字加减运算都费劲,还还是省省心吧。  

      4)那你说,在py2里好像也有bytes呀,是的,不过py2里的bytes只是对str做了个别名(python2里的str就是bytes, py3里的str是unicode),没有像py3一样给你显示的多出来一层封装,但其实其内部还是封装了的。 这么讲吧, 无论是2还是三, 从硬盘到内存,数据格式都是 010101二进制到-->b'xe4xbdxa0xe5xa5xbd' bytes类型-->按照指定编码转成你能看懂的文字

      5)编码应用比较多的场景应该是爬虫了,互联网上很多网站用的编码格式很杂,虽然整体趋向都变成utf-8,但现在还是很杂,所以爬网页时就需要你进行各种编码的转换,不过生活正在变美好,期待一个不需要转码的世界。

    (转自金角大王的博客)

    unicode都占两个字符

    ascii码英文都占一个字符

    Utf-8可变长的字符编码,里面所有英文字符一个字节,中文三个字节。

    字符编码的转换:

    不同编码之间的转换,需要unicode编码

    声明文件编码:

    #-*-coding:gbk-*-

    Python程序中默认unicode

    区分文件编码和程序中字符编码

      理解这句话:

      s="你好"

      print(s.encode("utf-8").decode("utf-8").encode("gb2312"))

    encode()转化为编码,通过decode()才能转化字符显示。

     

    三、文件的操作

     

    # 文本存储的原理
    # 1、打开编辑器就打开了启动了一个进程,是在内存中的,
    # 所以,用编辑器编写的内容也都是存放与内存中的,断电后数据丢失
    # 2、要想永久保存,需要点击保存按钮:编辑器把内存的数据刷到了硬盘上。
    # 3、在我们编写一个py文件(没有执行),跟编写其他文件没有任何区别,
    # 都只是在编写一堆字符而已。

     

     

    对文件操作的流程

    1)打开文件,得到文件的句柄,并赋值给一个变量

    2)通过句柄,对文件进行操作

    3)关闭文件

     

    打开文件的模式有:

    • r,只读模式(默认)。
    • w,只写模式。【不可读;不存在则创建;存在则删除内容;慎用】
    • a,追加模式。【可读;   不存在则创建;存在则只追加内容;】

    "+" 表示可以同时读写某个文件

    • r+,可读写文件。【可读;可写;可追加,最常用】
    • w+,写读
    • a+,同a

    "U"表示在读取时,可以将 自动转换成 (与 r r+ 模式同使用)

    • rU
    • r+U

    "b"表示处理二进制文件(如:FTP发送上传ISO镜像文件,linux可忽略,windows处理二进制文件时需标注)

    • rb
    • wb
    • ab

    打印进度条的例子:

    1 import sys,time
    2 
    3 for i in range(20):
    4     sys.stdout.write("#")
    5     sys.stdout.flush()
    6     time.sleep(0.1)
    打印进度条

    实际通过f.flush()方法,大家就会理解了为什么断电会数据丢失。

    计算机中硬盘和内存的处理数据的速度是不一样的,在向硬盘写数据时候,就需要写先入缓冲区中,写满了,一次性的写入硬盘中。突然断电,就会让缓冲区中的数据丢失。

    也就是说我们的程序中把再行过程中,程序显示的是写入了硬盘,实际是写在了缓冲区中,而没有及时写入硬盘,从而造成数据丢失。Python解决这个问题的办法就是f.flush()方法。

    文件的修改的办法:

    1)加载到内存中,修改!

    2)打开一个文件,修改后写在新文件中。

     1 修改
     2 f1=open("good_list.txt",'r+')
     3 f_new=open("good_list.bak.txt","w",encoding="utf-8")
     4                                 for line_1 in f1:
     5                                     if mod_goods in line_1:
     6                                         line_1=line_1.replace(re.split(":",line_1)[1],"%s:"%mod_price)
     7                                     f_new.write(line_1)
     8                                 f_new.flush()
     9                                 f1.close()
    10                                 f_new.close()
    11 
    12 #写回原文件
    13                                 f1=open("good_list.txt","w")
    14                                 f_new=open("good_list.bak.txt","r")
    15                                 for line_2 in f_new:
    16                                     f1.write(line_2)
    17                                 f1.flush()
    18                                 f1.close()
    19                                 f_new.close()
    文件修改的源代码(思路2)
     1 import sys
     2 f = open("yesterday2","r",encoding="utf-8")
     3 f_new = open("yesterday2.bak","w",encoding="utf-8")
     4 
     5 find_str = sys.argv[1]
     6 replace_str = sys.argv[2]
     7 for line in f:
     8     if find_str in line:
     9         line = line.replace(find_str,replace_str)
    10     f_new.write(line)
    11 f.close()
    12 f_new.close()
    文件修改-alex代码

    练习:

    #:实现:linux下vim中替换操作:
    # 例如: 1,5s/H/h/g 实现把前5行的H替换为h
    # 要求:行号,替换的内容,还有g都是输入的
    # n,m s /替换的内容 / 被替换的内容 /g
     1 str1="11,54s/'中国'/'云计算'/g"
     2 str1=str1.strip()
     3 hang1=int((str1.partition(",")[0]))
     4 hang2=int((str1.partition(",")[2].partition("s")[0]))
     5 bth=str1.split("/")[1]
     6 th=str1.split("/")[2]
     7 g=str1.split("/")[3]
     8 #测试切割
     9 print(hang1,hang2,bth,th,g)
    10 #文档修改的思路:
    11 lines=[]
    12 with open("123.txt","r",encoding="utf-8") as f:
    13     for line in f:
    14         if "H" in line:
    15             line=line.replace("H","h")
    16         lines.append(line)
    17 with open("123.txt","w",encoding="utf-8") as f:
    18     for i in lines:
    19         f.write(i)
    View Code

    练习2:

    编程程序,实现set nu  给文档每一行 添加一个行号:
     1 count=1
     2 lines=[]
     3 with open("123.txt","r+",encoding="utf-8") as f:
     4     for line in f:
     5         line=str(count)+": "+ line
     6         count=count+1
     7         lines.append(line)
     8     f.seek(0)
     9     for i in lines:
    10         f.write(i)
    View Code

    练习3:

    #编写函数,实现猜数字的游戏,随机生成1-20个数字,只能猜三次。
    #利用装饰器,给上面的游戏,增加一个用户判断的功能。
    #要求用户名和密码存在文件中。

    四、作业

    程序练习  

    程序1: 实现简单的shell sed替换功能

    程序2:修改haproxy配置文件 

    需求:

     1 1、查
     2     输入:www.oldboy.org
     3     获取当前backend下的所有记录
     4 
     5 2、新建
     6     输入:
     7         arg = {
     8             'bakend': 'www.oldboy.org',
     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.org',
    20             'record':{
    21                 'server': '100.1.7.9',
    22                 'weight': 20,
    23                 'maxconn': 30
    24             }
    25         }
    26 
    27 需求
    要求
     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         log global
    25         acl www hdr_reg(host) -i www.oldboy.org
    26         use_backend www.oldboy.org if www
    27 
    28 backend www.oldboy.org
    29         server 100.1.7.9 100.1.7.9 weight 20 maxconn 3000
    30 
    31 原配置文件
    原配置文件

    参考文献:

    http://www.cnblogs.com/alex3714/articles/5717620.html

    http://www.cnblogs.com/yuanchenqi/articles/5956943.html

     

     

     



     

    人的痛苦源于对自己无能的愤怒!
  • 相关阅读:
    ajax 发送请求无法重定向问题
    网页中转跳转的几种方式
    后台返回的HTML整个页面代码打开方法
    Json对象与Json字符串的转化、JSON字符串与Java对象的转换
    SpringMVC ModelAndView跳转失效
    springMVC中前台ajax传json数据后台controller接受对象为null
    $.ajax 中的contentType
    springMVC--请求的跳转和传值
    Windows NT WinLogon Notify
    虚拟机检测技术剖析
  • 原文地址:https://www.cnblogs.com/cx-ajun/p/7080773.html
Copyright © 2011-2022 走看看