zoukankan      html  css  js  c++  java
  • python数据类型补充,copy知识点及文件的操作

    数据类型的补充
    1,元组中里面如果只有一个元素,且没有逗号,则该数据类型与里面的元素相同
    1)例子
    tu1 = ('lannanhai')
    tu2 = ('laonanhai',)
    print(tu1,type(tu1)) #字符串
    print(tu2,type(tu2)) #元组
    2)例子
    tu1 = (1)
    tu2 = (1,)
    print(tu1,type(tu1)) #整数
    print(tu2,type(tu2))#元组

    **************list列表小知识点**************

    l1 = [111,222,333,444,555,666,777,888,999,]
    del l1[1::2]
    print(l1) #删除index为奇数的元素,用del 切片
    或者用 for循环 但是的从倒着删除 不会改变索引值
    for index in range(len(l1)-1,-1,-1): for循环最好不要改变他的长度
    ***************dict字典**********************
    1) dic = dict.fromkeys('abc',666)# 可迭代添加 这个作用是创建新的一个字典
    #{‘a’:666,'b':666,'c':666}
    一个这个fromkeys有个bug
    dic = dict.fromkeys([1,2,3],[]) # 前面无论是什么数据类型 ,迭代的是其中的元素
    注意:
    dic = dict.fromkeys([1,2,3],[])
    dic[1].append(666)
    print(id(dic[1]),id(dic[2]),id(dic[3])) id地址一致
    dic[1].append(666)
    print(dic) # {1:[666],2:[666],3,[666]} # 说明fromkeys中的第二个参数位置id是固定不变得
    2) dic = {'k1':'v1','k2':'v2','k3':'v3','name':'alex'}
    for i in dic:
    if 'k' in i:
    del dic[i] # 这样会报错,程序无法进行,因为改变了dict的大小。
    所以在循环dict中,最好不要改变dict的大小,会影响结果或者报错。
    dic = {'k1':'v1','k2':'v2','k3':'v3','name':'alex'} #正确方法 主要记得使用‘In’的方法,这个没记牢。
    l1 = []
    for i in dic:
    if 'k' in i:
    l1.append(i)
    print(l1)
    for key in l1:
    del dic[key]
    print(dic)
    **********************数据类型的转换***********************
    1):
    str --->list split()
    list --->str join()
    2):
    tuple ---->list list()
    例子 tu1 = (1,2,3)
    l1 = list(tu1)
    print(l1)
    list --->tuple tuple()
    3):
    dic ---> list list()注意 这样只能将字典中的键给转换成列表

    list --->dic dict()注意 无法成功,会报错。
    4)list ---> set set() 但要注意list里面必须不可变的元素组成的,否则无法转化,会报错。好的是可以为列表转化为集合 直接去重了
    set ----> list
    5)
    数字0,‘’,[],(),{}---->bool 为Fasle
    *************************set集合***********************
    集合是一个可变的数据类型,他是以{}形式存在的,里面是一个一个的元素无键值对
    空集合set()
    set{}是个空字典
    但是它要求它里面的元素是不可变得,集合是无序的,不重复的。
    作用 1,去重 本身带有去重功能set1 = {11,11,11,22}
       2,关系测试
    集合的增删改,因为是无序的无法查

    set.add(元素) 增加的是无序的
    set.update(元素)迭代添加 按照最小的元素增加

    set.remove(元素)
    set.pop()随机删除,有返回值
    set.clear()清空 得出 set() 创建空集合 set1 = set()
    整体删除 del set

    只能for循环 遍历查询
    for i in set1:
    print(i) #得出的是无序的

    ***************set集合的关系测试***************
    交集 & intersetion
    set1 = {1,2,3,4,5}
    set2 = {4,5,6,7,8}
    print(set1 & set2)
    并集 | union
    差集 - difference :得到set1 独有的元素 (除去了两则的交集值)
    反交集:^ symmetric_difference
    子集 set1 <set2 issubset "<"返回True 那么set1是set2的子集
    set1 = {1,2,3}
    set2 = {1,2,3,4,5,6,}
    超集 set2 <set1 issuperset ">"返回True set2是set1的超级

    set = frozenset({1,2,3,'aqwe'})
    将集合冻结 有可变变成不可变得数据类型,可以做字典的键等 类型type是 frozenset类型
    ***********************copy复制*****************************
    l1 = [1,2,3]
    l2= l1
    l2.append(666)
    print(l1,l2)#[1,2,3,666] [1,2,3,666] 说明l1和l2在内存中只是一个
    #对于赋值运算来说,指向的都是同一个内存地址,一变都变。

    1)浅copy
    l1 = [11,22,33]
    l2 = l1.copy()
    l1.append(666)
    print(l1,l2) #l1= [11,22,33,666] l2= [11,22,33]
    print(l1,id(l1))
    print(l2,id(l2)) id地址不一样,值也不一样。

    l1 = [11,22,['barry']]
    l2 = l1.copy()
    l1[2].append('alex')
    print(l1,id(l1))
    print(l2,id(l2)) id地址不一样 但是l1 和 l2相同。
    print(l1,id(l1[-1]))
    print(l2,id(l2[-1])) 列表里的列表 id地址一样
    对于浅copy来说,第一层创建的是新的内存地址,而从第二层开始,指向的都是同一个内存地址,所以对于第二层以及更深的层数来说,保持一致性。
    对于切片来说,它是浅copy
    l1 = [1,2,3,4,5,6,[11,22]]
    l2 = l1[:]
    l1.append(666)
    print(l1,l2) # l1 = [1,2,3,4,5,6,[11,22],666] l2=[1,2,3,4,5,6,[11,22]]
    l1[-1].append(666)
    print(l1,l2) # l1 = [1,2,3,4,5,6,[11,22,666]] l2=[1,2,3,4,5,6,[11,22,666]]
    2)深copy
    import copy #引入一个模块
    l2 = copy.deepcopy(l1)
    深copy各层均是独立的。

    对于浅copy来说,只是在内存中重新创建了开辟了一个空间存放一个新列表,但是新列表中的元素与原列表中的元素是公用的。


    对于深copy来说,列表是在内存中重新创建的:列表中可变的数据类型是重新创建的,列表中的不可变的数据类型是公用的。


    注意:
    l1 = [1,2,3] #根据学的小数据池知道,列表没有小数据池的,只有字符串str和int有。
    l2 = [1,2,3]
    l1.append(666)
    print(l1,l2) #l1 = [1,2,3,666] l2=[1,2,3]

    切片

    l1 = [1,2,3,[11,22]]

    l2 = l1[:]

    l1.append(666)

    print(l1,l2)   结果是不一样的 即第一层id地址是不一样的

    l1 = [1,2,3,[11,22]]

    l2 = l1[:]

    l1[-1].append(666)

    print(l1,l2)   结果是一样的,即切片是浅copy

    *********************文件操作**************************
    python代码:
    path 文件路径:
    encoding 编码方式: utf-8 gbk....这里的意思是用什么编码方式解码
    mode 操作方式: 只读 只写 追加 读写 写读......
    f1 = open('d:python练习.txt',encoding = 'utf-8',mode = 'r')
    print(f1.read())
    f1.close()
    # f1 变量f1_obj f1_file file file_handle 文件句柄
    #open : python的内置函数,但是底层调用的是windows系统的open功能,open功能就是操作文件用的
    注意: windows系统默认的编码方式gbk ;linux,macos:utf-8

    流程:1,打开文件,产生文件句柄
        2,对文件句柄进行操作
        3,关闭文件
    路径:绝对路径:从根目录开始一直找到文件。
    相对路径:从当前目录开始找到的文件。操作同一文件的其他文件。

    f1 = open('d:python练习.txt',encoding = 'utf-8',mode = 'r')#绝对路径
    print(f1.read())
    f1.close()

    f1 = open('python练习.txt',encoding = 'utf-8',mode = 'r')#相对路径
    print(f1.read())
    f1.close()

    ###utf-8和gbk之间英文字符 数字 特殊字符可以直接转换,但是中文不行,原因是gbk和utf-8对于字母,数字,特殊字符的编码都是引用ascii码,所以可以直接转换。
    //读
    r模式:如果一个文件不设置mode ,那么默认使用功能r模式 只读操作文件
    读返回的是字符串
    在r模式下 read(n)n是字符 在rb模式下 read(n)读的是字节
    1)read()将文件中的内容全部读取出来,但是如果文件很大就会很占内存,甚至导致内存崩溃

    2)read(n) 在只读模式下,n按照字符读取 即 读到文件中的那个字符
    3)readline()读取每次只读取一行,注意:readline()读取出来的数据在后面都有一个
    解决办法是在文件后面加一个strip() 里面也可以加数字readline(n)
    msg1 = f.readline().strip()
    4)readlines() 返回一个列表,列表里面每个元素是原文件的每一行,如果文件很大,占内存,崩盘。
    以上都不是很好,大文件读取困难
    5)for循环
    可以通过for循环去读取,文件句柄是一个迭代器,它的特点是每次循环只在内存中占一行的数据,非常节省内存。

    f1= open(r'D:python练习2.txt',encoding='gbk',mode= 'r+' )
    for line  in f1:
        print(line)
    f1.close

    注意 读完的文件句柄要关闭
    rb模式:文件指针将会放在文件的开头凡是带b 不用声明encoding 
    二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。记住下面讲的也是一样,带b的都是以二进制的格式操作文件,他们主要是操作非文字文件:图片,音频,视频等,并且如果你要是带有b的模式操作文件,那么不用声明编码方式。
    rb模式中也有 read read(n) readline() readlines() for循环这几种。
    r+模式 只的是加一个可以写 及 读写
    先读后写一定要按照顺序 先读 后写
    r+b模式
    //写
    w模式:write:只写模式 不可读
    如果文件不存在,利用w模式操作文件,那么它会先创建文件,然后写入内容.
    如果文件存在,利用w模式操作文件,先清空原文件内容,在写入新内容
    wb模式:
    以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如:图片,音频,视频等。
    w+模式 写读模式
    f1 = open('D:python练习.txt',encoding = 'gbk',mode = 'w+')
    f1.write('666666666666666')
    f1.seek(0) #调整光标,将光标位置放在起始位置,否则读不出数据。移动到结尾:seek(0,2) seek的第二个参数表示的是从哪个位置进行偏移,默认是0,表示开头,1表示当前位置,2表示结尾
    print(f1.read())
    seek定义:是以字节调节光标的位置。
    f1. seek(offset[, whence])

    whence:0,1,2三个参数,0表示文件开头,1表示当前位置,2表示文件结尾

    offset:偏移量,可正可负,正数表示向后移动offset位,负数表示向前移动offset位。
    f1.close()
    f1.tell(): 可以获取当前光标在什么位置
    f1.readable()判断是否可读
    f1.writable()判断是否可写
    f1.flush()刷新文件内部缓冲区 也就是强制保存
    f1.fileno()通过文件描述符找到这个文件
    f1.truncate(n)按照字节对源文件进行截取,只留0......n字节的数据 只能从头开始
    w+b模式
    //追加

    打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。

    新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
    a模式 只追加模式,不可读
    a:没有文件,创建文件写内容
    a:如果有文件,最后面追加内容。
    ab模式
    a+模式 先追加后读
    a+b模式
    *****************打开文件的另一种方式********************
    1,利用with上下文管理这种方式,他会自动关闭文件句柄
    with open('t1',encoding='utf-8') as f1:
    f1.read()
    2,一个with 语句可以操作多个文件,产生多个文件句柄
    with open('t1',encoding='utf-8') as f1, #加个‘,’号就行了 ‘’是转行符
    open('Test', encoding='utf-8', mode = 'w') as f2:
    f1.read()
    f2.write('老男孩老男孩')
    经验小记:
    wtih open('D:python练习.txt',encoding = 'gbk',mode='r') as f1:
    content = f1.read()
    pass
    with open('D:python练习.txt',encoding = 'gbk',mode='w') as f2:
    f2.write('qwer')
    #因为是对同一个文件进行读 写 在第一个with语句中 很有可能文件句柄f1未关闭情况下走到
    #第二个with语句中对这个文件进行 重新打开这个文件 进行 写 这时候很容易出错,所以可以主动关闭
    wtih open('D:python练习.txt',encoding = 'gbk',mode='r') as f1:
    content = f1.read()
    f1.close() # 主动关闭,避免出错
    pass
    ************************************************************

    文件的修改:

    文件的数据是存放于硬盘上的,因而只存在覆盖、不存在修改这么一说,我们平时看到的修改文件,都是模拟出来的效果,具体实现步骤如下:

    对文件的改,实际的步骤:
    1,打开原文件old_file,将原内容读取到内存
    2,创建一个新文件new_file
    3,将原内容通过你的改写形成新内容,写入到新文件。
    4,将原文件删除。
    5,将新文件重命名成原文件。
    方法一:
    import os
    with open('D:python练习.txt',encoding = 'gbk') as f1,
    open('D:新文件.txt',encoding = 'gbk',mode='w') as f2:
    old_content = f1.read()
    new_content = old_content.replace('ABC','qwe')
    f2.write(new_content)
    os.remove('D:python练习.txt') #删除原文件
    os.rename('D:新文件.txt','D:python练习.txt') #更改新文件名字
    ################有个缺陷 如果文件很大就会崩溃
    方法二:
    import os
    with open('D:python练习.txt',encoding = 'gbk') as f1,
    open('D:新文件.txt',encoding = 'gbk',mode='w') as f2:
    for line in f1:
    new_line = line.replace('ABC','qwe')
    f2.write(new_line) #在for里面所以没有清空,一直在写,没有结束。
    os.remove('D:python练习.txt') #删除原文件
    os.rename('D:新文件.txt','D:python练习.txt') #更改新文件名字
    *******************************************************

    经验小知识:
    对于添加的元素是有规律性的 每列同属性,那么可以将属性放在开头 这样在增加列 可以在问价开头增加属性。
    goods_info = []
    l1 = ['name','price','amount']

    with open('D:python练习.txt',encoding = 'gbk') as f1:
    for line in f1:
    line = line.strip().split()
    dic = {}
    for i in range(len(line)):
    dic[l1[i]]=line[i]
    print()
    goods_info.append(dic)
    print(goods_info)

  • 相关阅读:
    基本数据结构——栈
    错误 1 error C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. d:usersvs2013le
    Java内存区域
    VS2010 无法计算HKEY_LOCAL_MACHINESOFTWAREMicrosoftMSBuildToolsVersions14.0@VCTargetPath处的属性表达式
    PHP高并发场景下的一点思路
    LINUX运维常用命令
    php7的一些新特性总结
    MySQL读写分离主从配置
    php 生成唯一id的几种解决方法
    浅谈mysql两种常用引擎MyIASM和InnoDB的区别
  • 原文地址:https://www.cnblogs.com/xiao-xuan-feng/p/12153175.html
Copyright © 2011-2022 走看看