本节内容

  1. 元组操作
  2. 字典操作
  3. 文件操作的初步认识

 

 

一、元组

  1.元组其实跟列表差不多,也是存储一组数据的,只是它一旦创建,便不能再修改的。

  例如:

    names =("zhangsan","lisi","wangwu")

  它只有两个方法,一个是count,一个是index,同样它也可以切片。

  

names = ("zhangsan","lisi","wangwu","zhangsan")
 print(names.count("zhangsan"))
   print(names.index("lisi")) 
   print(names[1:])    
  print(names[:2]) 
       .       
       . 
       . 
二、字典的操作

   字典是一系列的键-值对。每个键都与一个值相关联,你可以使用键来访问与之对应的值。与键相关联的值可以是数字、字符串、列表乃至字典。
事实上可以将任何python对象用作字典的值。
info = { "name1":"zhangsan",
     "name2":"lisi",
      "name3":"wangwu" }
   字典的特性:
         无序的         
         key必须是唯一的,所以天生去重
1、访问字典中的值
     print(info["name2"])
        判断一个key在不在字典中
     print("names1" in info)
     返回True存在 False 不存在
     print(info.get("names1"))
   存在返回值,不存在返回None print(info.get("names","panglicai")) 
    可以跟个参数“panglicai”,当不存在是可以打印panglicai

2、增加键-值对
     info["names4"] = "zhaoliu"
     info["names5"] = ["zhaoliu",22]
     info["names6"] = {"names":"zhaoliu","age":22}
3、修改一个键-值对
     info["names5"][1] = 33
     info["names6"][names] = "plc"

4、删除
     info.pop()
     info.pop("names1") 删除后会返回删除的值
     info.pop("names7")删除不存在的会报错
     info.pop("names7","mei")当添加参数后,删除不存在的会显示指定的参数mei而不会再报错
     del删除后不会返回删除的值
     del info["names2"] 删除后的键-值对会永远消失
5、fromkeys()
      names = ["alex","jack","rain"]
       print(dict.fromkeys(names,0))
>>{'alex': 0, 'jack': 0, 'rain': 0}
        会把names列表中的每个元素当做key 然后把指定的参数0当做value
     相当于这三个key值指向的都是同一个value可以通过id看内存的地址的方法 
      print(id(n1["alex"]),id(n1["rain"]))
     >> 1512064640 1512064640 
    当指定的参数是字符串或数字时,可以修改其中的值     
    n1 = dict.fromkeys(names,0)
     n1["jack"] = 2
     print(n1)     
    >>{'alex': 0, 'jack': 2, 'rain': 0}
      可以看到只有jack对应的值变了相当于(a=10 b=a a =11 b还是10的原理一样)
当指定的参数是一个列表时修改其中的一个值,其字典中的值都会变
     n1 = dict.fromkeys(names,[1,2,3])
     n1["jack"][1] = 4
     print(n1)
     >>{'alex': [1, 4, 3], 'jack': [1, 4, 3], 'rain': [1, 4, 3]}
     结果会把所有key相关联的value都改了
   因为当其中一个列表的值变化时它不会开辟一块新空间来存储,而是在原列表中直接修改,
    并且原来的指向关系也没有发生变化,所以列表中的其中一个元素发生变化,
    其他的key相关联的value也跟着变。
6、items()
    一般用于循环 
     names = {"name1":"alex","name2":"rain","name3":"jack"}
    效率低
     for k,v in names.items():  
        print(k,v)
    >>name1 alex                       
      name2 rain     
       name3 jack  
    相当于:for key in names:
          print(key,names[key])     
       效率高

    keys.() 只循环所有key 默认也只循环key 
      values.() 只循环所有的值 

7、popitem() 随机删除一个键-值对

8、setdefaul 获取键-值,如果没有则添加
   print(names.setdefaul("name4","plc"))
   如果存在name4 则显示name4对应的key,如果没有则把name4:plc 添加到names字典中
  
9、update() 合并两个字典,当新字典中出现原来字典的键但值不一样时,合并时按新的来。  

10、.copy()
   info = {"No1":"alex","No2":"rain","No3":{"name":"alex","age":22}}
    info2 = info.copy()
    print(info)
    print(info2)
  >>{'No1': 'alex', 'No2': 'rain', 'No3': {'name': 'alex', 'age': 22}}
    {'No1': 'alex', 'No2': 'rain', 'No3': {'name': 'alex', 'age': 22}}
  可以看到两份数据是一样的,因为它们指向的都是同一个内存空间。
  当修改原来的数据时看coyp是否有变化
  info2["No2"] = "RAIN"
  print(info)
  print(info2)
>>{'No1': 'alex', 'No2': 'rain', 'No3': {'name': 'alex', 'age': 22}}
{'No1': 'alex', 'No2': 'RAIN', 'No3': {'name': 'alex', 'age': 22}}
  可以看到不一样了,再次修改内置字典的值看是否还有变化
  info2["No3"]["age"] = 30
  print(info)
  print(info2)
  >>{'No1': 'alex', 'No2': 'rain', 'No3': {'name': 'alex', 'age': 30}}
    {'No1': 'alex', 'No2': 'RAIN', 'No3': {'name': 'alex', 'age': 30}}
可以看到两份数据都变了。What happend ?
其实和前面说过的fromkeys(),原来是一样的,当你修改一个key(修改第一层)时它会重新开辟一块内存空间,原来的指向就会发生改变,
  当你修改字典中一个内置字典或列表时,它不会开辟新的内存空间,原来的指向都不会变,所以两份数据是一样的.
11、如果想要独立的copy数据(copy出来的数据和原理的数据指向不一样)
  引入函数 import copy
  import copy
  info = {"No1":"alex","No2":"rain","No3":{"name":"alex","age":22}}
  info3 = copy.deepcopy(info)
  print(info)
  print(info3)
  >>{'No1': 'alex', 'No2': 'rain', 'No3': {'name': 'alex', 'age': 22}}
   {'No1': 'alex', 'No2': 'rain', 'No3': {'name': 'alex', 'age': 22}}
  可以看到两份数据也同样是一样的
  这次再按照前面的修改时,看下变化
  info3["No2"] = "RAIN"
  print(info)
  print(info3)
  >>{'No1': 'alex', 'No2': 'rain', 'No3': {'name': 'alex', 'age': 22}}
   {'No1': 'alex', 'No2': 'RAIN', 'No3': {'name': 'alex', 'age': 22}}
  再修第二层的值时
  info3["No3"]["age"] = 33
  print(info)
  print(info3
  >>{'No1': 'alex', 'No2': 'rain', 'No3': {'name': 'alex', 'age': 22}}
   {'No1': 'alex', 'No2': 'RAIN', 'No3': {'name': 'alex', 'age': 33}}
12、小知识点:
      字典的查询速度比列表快,因为字典的key是唯一的,字典通过hash实现的key唯一
      hash是把字符串通过一定的数学算法生成唯一的数值序列,生成的数值是在当前的
      的程序中唯一。
      hash会把key转化成数值后自动排序,再通过二分法查找,而列表再查找时,
      得自己内部先排序,再通过二分等算法查找。

三、文件操作基础
  1、文件操作流程:
    打开一个文件,得到文件句柄并赋值给一个变量
    通过句柄对文件操作
    关闭文件
  2、基本操作:
    打开文件: file只能在2.x系列中
    open() 例如打开文件lyric并查看
    print(open("lyric"))
     >> <_io.TextIOWrapper name='lyric' mode='r' encoding='cp936'>
    相当于打开了文件对象,并没有把数据加载到内存,是在硬盘上找到了文件了并且获取了它的位置,把文件对象打印到了内存
    要把数据加载到内存可以通过:print(open("lyric",encoding="utf8").read())
    这样就可以显示lyric文件内容了,要对文件进行操作,先对加载到内存的文件赋个变量
    data = open("lyric",encoding="utf8").read() 然后在进行修改,例如替换某个字符串
    print(data.replace("Somehow","HHHAAA")) 把字符串Somehow 替换成 HHHAAA,可以实现
    下一步要保存修改后的文件到硬盘,该如何操作呢?
    现在无法保存了,因为你打开文件对象后直接read了并赋值给data了,所以open("lyric",encoding="utf8")的文件位置并没有
    保存下来,就丢了找不到了。
    所以要打开文件后并赋值保存它的位置:f = open("lyric",encoding="uft8")
     然后再去读:data = f.read()
    再去修改:data = data.replace("Somehow","HHHAAA")
    最后再去写入硬盘:f.write(data) 能否成功呢?显然是不能会报文件不能写的错误
    因为python在操作文件时,要么是打开只读的,要么是打开只写的。python的默认模式就是以读打开的
  3、打开文件的模式有: 
       r,只读模式(默认)。
      w,只写模式。【不可读;不存在则创建;存在则删除内容;】
      a,追加模式。【可读;   不存在则创建;存在则只追加内容;】
  "+" 表示可以同时读写某个文件
     r+,可读写文件。【可读;可写;可追加】
     w+,写读
     a+,同a
  "U"表示在读取时,可以将 \r \n \r\n自动转换成 \n (与 r 或 r+ 模式同使用)
     rU
     r+U
  "b"表示处理二进制文件(如:FTP发送上传ISO镜像文件,linux可忽略,windows处理二进制文件时需标注)
     rb
     wb
     ab
    所以对文件正确的打开方式是:
    f = open("lyric",mode="r",encoding="utf-8") 以读的模式打开
     f = open("lyric",mode="w",encoding="utf-8") 以写的模式打开
    以读模式打开的文件不能写,以写模式打开的文件不能读,当以写模式打开文件后
    相当于创建文件,原有的文件会被覆盖,直接关闭会保存:f.close()
    那该怎么修改文件后保存呢:
    1、以r模式打开 
       f = open("lyric",mode="r",encoding="utf-8")
       data = f.read()
      data = data.replace("Somehow","HHHAAA")
      f.close()
      f = open("lyric",mode="w",encoding="utf-8") 
      f.wite(data)
      f.close()
      这样就可以修改后并保存了,但是这种方法太吃内存需要把文件全读到内存。

    2、一行一行的读,读完一行后再写到新文件中,然后把旧文件删掉,把新文件名改成旧文件的名
      但是当读完时刻,新文件也写完了,这时会有两文件占两倍的硬盘空间。
      一行行读的语法.readline()
      for line in f:
        print(line)相当于print(f.readline())
      读取前五行:
        for i in range(5):
          print(f.readline().strip())
        或者:
        line_nu = 0
        for line in f:
          if line_nu < 5:
            print(line.strip())
            line_nu += 1
          else:
              break
        
      要删除旧文件并且把新文件重命名想,需要引入 os 函数
      完整的代码:
      import os
      f = open("lyric",mode="r",encoding="utf-8")
      f_new = open("lyric_new",mode="w",encoding="utf-8")
      for line in f:
          if "HHHAAA"in line:
             line = line.replace("HHHAAA","Somehow")
       f_new.write(line)
      f.close() f_new.close()
      os.remove("lyric")
      os.renames("lyric_new","lyric")