目录
集合操作
文件操作
字符编码与转码
函数
一、集合操作
集合是一个无序的,不重复的数据组合,它的主要作用如下:
- 去重,把一个列表变成集合,就自动去重了
- 关系测试,测试两组数据之前的交集、差集、并集等关系
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、函数基本语法及特性
函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可。函数是逻辑结构化和过程化的一种编程方法。
特性:
- 代码复用
- 使程序变的可扩展
- 使程序变得易维护
语法定义
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、返回值
- 函数在执行过程中只要遇到return语句,就会停止执行并返回结果
- 如果未在函数中指定return,那这个函数的返回值为None
返回值个数 :返回类型
=0 :None
=1 :object
>1 : tuple
5、递归
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
def calc(n):
print(n)
if int(n/2) ==0:
return n
return calc(int(n/2))
calc(10)
递归特性:
- 必须有一个明确的结束条件
- 更深一层递归时,问题规模相比上次递归都应有所减少
- 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(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()