Python(三)集合、文件操作、字符编码和函数

目录

集合操作
文件操作
字符编码与转码
函数

一、集合操作

集合是一个无序的,不重复的数据组合,它的主要作用如下:

  • 去重,把一个列表变成集合,就自动去重了
  • 关系测试,测试两组数据之前的交集、差集、并集等关系

1、常用操作

去重
    list_1 = [1,1,2,3,4,5,6,6,7,7,8,8,9,9,3]
    set_1 = set(list_1)
    >>> set_1
    {1, 2, 3, 4, 5, 6, 7, 8, 9}
    # 集合用{}表示
交集 
    set_2 ={0,2,3,4}
    set_1.intersection(set_2)
并集:
    set_1.union(set_2)
差集:
    set_1.difference(set_2)
    # in set_1 but not in set_2
子集:
    set_1.issubset(set_2)
父集:
    set_1.issuperset(set_2)
对称差集:(并集去除交集,即并集和交集的差集)
    set_1.symmetric_difference(set_2)
    (set_1 | set_2) - (set_1 & set_2)
判断有没有交集,无交集,返回True
    set_1.isdisjoint(set_2)

2、符号操作

    & : 交集        intersection
    | :并集        union
    - :差集        difference
    s <= t :子集   issubset
    s >= t :父集   issuperset
    ^ :对称差集    symmetric_difference

3、集合增删改查

添加:
    set_1.add(99)
批量添加
    set_1.update([1,2,3,4])
删除:
    set_1.remove('h')  # 没有则报错
    set_1.discard(99)  # 在则删除,不在就不操作。无返回信息
随机删:
    set_1.pop()
长度:
    len(set_1)
是否属于判断
    s in set_1  # (判断成员在不在都是这么写,字典中判断key)
返回 set “s”的一个浅复制 
    s.copy()  

二、文件操作

对文件操作流程
1. 打开文件,得到文件句柄并赋值给一个变量
2. 通过句柄对文件进行操作
3. 关闭文件

如下代码运行,“print(date2)”会打印test文件内容么?

f = open("test", 'r', encoding='utf-8')  # 文件句柄:文件内存对象
data = f.read()
data2 = f.read()
print(data)
print("date2".center(20, "-"))
print(data2)

是不会有内容的,当运行“data = f.read()”时,文件句柄已经移动到文件末尾,再次读取是取不到内容的。需要使用“seek”移动文件句柄
1、文件打开模式

    r: 只读,不加模式默认为r
    w:只写,以写去创建文件,
    a;追加,不支持读

"+" 表示可以同时读写某个文件
    r+ :读写--可读、可写、可追加
    w+ :写读--先创建文件,再写(在原文件上的修改都是覆盖操作)
    a+ :追加读--默认打开句柄在末尾,读取需先seek(0)指定位置,一写句柄就到末尾了
    #   r和w,seek指定句柄可以覆盖修改,a+指定句柄也是追加

"U"表示在读取时,可以将 \r \n \r\n自动转换成 \n (与 r 或 r+ 模式同使用)
    rU
    r+U
    # windows上换行符为 \r\n

"b"表示处理二进制文件
    rb:二进制文件读
    wb:二进制文件写
    ab:追加二进制
# 文件存在硬盘上都是二进制,前边说encoding='utf-8'是指把二进制转换成utf-8编码打开,
# 而“b”是指,不用转换编码,我直接读取二进制

2.1、文件操作

open("1.txt", 'r', encoding="utf-8").read()
# encoding="utf-8",utf-8编码打开文件,windows下默认gbk打开

f.read()                # 读取文件句柄到结束所有内容
f.write("天安门")       # r和w模式,为句柄处覆盖写入,a模式写到最后
f.flush()               # 强制刷新(默认缓冲区满了存入磁盘)
f.close()               # 文件关闭
f.closed()              # 判断文件是否关闭

f.read(5)               # 读取5个字符
f.tell()                # 查看文件句柄位置。按照字符计数
f.seek(0)               # 移动文件句柄到第0个字符位置

f.encoding              # 文件编码
f.truncate()            # 什么不写清空文件
f.truncate(10)          # r模式截断出前10个字符,其他模式还是清空
  • 关于文件读取:

f.readline()和f.readlines()的区别:

区别加载内容类型
f.readline()句柄所在行字符串
f.readlines()所有行加载为列表列表

所以,f.readlines()通过下标就可以知道当前在哪一行了。但和f.read()一样都是文件全加载到内存中,文件大的话内存就占满了。

  • 推荐读取方式:
for line in f:  # f 变成了迭代器
    print(line)
    # 判断行的话,需自己加个计数器
  • 程序:模拟yum安装时的进度条
import sys, time

for i in range(20):
    sys.stdout.write("#")
    sys.stdout.flush()
    time.sleep(0.5)

2.2 文件内容修改
前面说的文件修改,只是对原内容覆盖,并不会插入内容,原内容往后移,因为这样有可能就把其他文件覆盖了,文件发生损坏。so:
文件修改两个办法:
1. 加载到内存,内存修改,覆盖写回
2. 另打开一个文件,修改完写到新文件中

with open("test", 'r', encoding='utf-8') as f, \
    open("test.tmp", 'w', encoding='utf-8') as f_new:

    for line in f:
        if "聚焦头条" in line:
            line = line.replace("聚焦头条","fgf")
        f_new.write(line)

# os.path.exists("test.bak")  判断文件是否存在
# os.remove("test.bak")       删除文件
# os.rename(test.tmp, test)   重命名

3.文件关闭(with语句)
为了避免打开文件后忘记关闭,可以通过管理上下文,即:

with open('log') as f:
    pass

如此方式,当with代码块执行完毕时,内部会自动关闭并释放文件资源。
在Python 2.7 后,with又支持同时对多个文件的上下文进行管理

三、字符编码与转码

1、Python编码详解
为什么我们要加“#-*- coding:utf-8 -*-”这一行?意思是置顶编码类型为utf-8编码!
为什么我们能看到这些文字、数字、图片、字符、等等信息呢?大家都知道计算机本身只能识别 0 1 的组合,他们是怎么展示这些内容的呢?我们怎么和计算机去沟通呢?
那怎么办?如何让计算机理解我们的语言,并且我们能理解计算机的语言呢?
ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。它是现今最通用的单字节编码系统,并等同于国际标准ISO/IEC 646。

在存储英文的时候我们至少需要1个字节(一个字母),就是8位(bit),看下ASCII表中1个字节就可以表示所有的英文所需要的字符,是不非常高效!

为什么呢?早期的计算机的空间是非常宝贵的!

那你会发现1个字节8位,他能存储的最大数据是2的8次方-1 = 255,一个字节最多能表示255个字符 那西方国家他们使用了127个字符,那么剩下字符是做什么的呢?就是用来做扩展的,西方人考虑到还有其他国家。所以留下了扩展位。
ASCII到了其他国家,完全不够用,于是就在原有的扩展位中,扩展出自己的gbk、gb2312、gb2318等字符编码。
他是怎么扩展的呢?比如说在ASCII码中的128这个位置,这个位置又指定一张单独表
于是每个国家都有自己的字符编码,也产生了1、没有字符集: 2、字符集冲突
为了统一起来,Unicode(统一码、万国码、单一码)是一种在计算机上使用的字符编码Unicode(统一码、万国码、单一码)是一种在计算机上使用的字符编码
它为每种语言中的每个字符设定了统一并且唯一的二进制编码,
规定虽有的字符和符号最少由 16 位来表示(2个字节),即:2 **16 = 65536, 注:此处说的的是最少2个字节,可能更多。
这里还有个问题:使用的字节增加了,那么造成的直接影响就是使用的空间就直接翻倍了!

为了解决个问题就出现了:UTF-8编码
UTF-8编码:是对Unicode编码的压缩和优化,他不再使用最少使用2个字节,而是将所有的字符和符号进行分类:ascii码中的内容用1个字节保存、欧洲的字符用2个字节保存,东亚的字符用3个字节保存…
OK 上面了解了:
1、什么ASCII编码
2、什么Unicode编码
3、什么UTF-8编码
回顾下乱码的出现原因:1、没有字符集 2、字符集冲突
2、Python编码转换
python3中,默认就是unicode编码

name = '中国'
# 转为UTF-8编码
print(name.encode('UTF-8'))
# 转为GBK编码
print(name.encode('GBK'))
# 转为ASCII编码(报错为什么?因为ASCII码表中没有中文字符集~~)
print(name.encode('ASCII'))

Python2.X中的编码转换
python2.X中默认是ASCII编码,你在文件中指定编码为UTF-8,但是UTF-8如果你想转GBK的话是不能直接转的,的需要Unicode做一个转接站点

#-*- coding:utf-8 -*-
import chardet

tim = '你好'
print chardet.detect(tim)
# 先解码为Unicode编码,然后在从Unicode编码为GBK
new_tim = tim.decode('UTF-8').encode('GBK')
print chardet.detect(new_tim)

# 结果
'''
{'confidence': 0.7525, 'encoding': 'utf-8'}
{'confidence': 0.99, 'encoding': 'GB2312'}
'''

声明只是文件的编码,python 3 的变量都是Unicode编码

四、函数

1、程序设计方法

程序设计方法特性
面向过程过程 def函数没有返回值
面向对象类 class
函数式编程函数 def函数有返回值

(不定义return,python隐式返回None。函数和函数式编程不是一回事,思想更接近数学运算,数学上的函数。一种抽象成都很高的编程范式。。函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数)

2、函数基本语法及特性
函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可。函数是逻辑结构化和过程化的一种编程方法。
特性:

  1. 代码复用
  2. 使程序变的可扩展
  3. 使程序变得易维护

语法定义

def sayhi():  # 函数名
    print("Hello, World")

sayhi()  # 调用函数

3、函数参数与局部变量
形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量

实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值
默认参数非必须传递
关键参数
正常情况下,给函数传参数要按顺序,不想按顺序就可以用关键参数,只需指定参数名即可,但记住一个要求就是,关键参数必须放在位置参数之后。
非固定参数
*args 会把多传入的参数变成一个元组形式
**kwargs 会把多传入的参数变成一个字典形式

def test(**kwargs):
    pass
# 传**kwargs参数的两种形式
test(name='fgf', sex='N')
test(**{'name':'fgf','sex':'N'})

全局与局部变量
在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。
全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序。

顶级的都是全局变量,函数中变量修改,函数中加global 变量名
不应该在函数里改全局变量,因为来回调用,就乱了。
列表、字典、集合可以在函数中修改。

4、返回值

  1. 函数在执行过程中只要遇到return语句,就会停止执行并返回结果
  2. 如果未在函数中指定return,那这个函数的返回值为None
返回值个数 :返回类型
        =0None 
        =1 :object
        >1 : tuple

5、递归
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。

def calc(n):
    print(n)
    if int(n/2) ==0:
        return n
    return calc(int(n/2))

calc(10)

递归特性:

  1. 必须有一个明确的结束条件
  2. 更深一层递归时,问题规模相比上次递归都应有所减少
  3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)

6、匿名函数

#这段代码
def calc(n):
    return n**n
print(calc(10))

#换成匿名函数
calc = lambda n:n**n
print(calc(10))

匿名函数主要是和其它函数搭配使用的,如下

res = map(lambda x:x**2,[1,5,7,4,8])
for i in res:
    print(i)

7、高阶函数
变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。

def add(x,y,f):
    return f(x) + f(y)


res = add(3,-6,abs)
print(res)

转载请务必保留此出处:http://blog.csdn.net/fgf00/article/details/52167245


eval()

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值