您的位置:首页 > 编程语言 > Python开发

Python 笔记 - 集合和文件操作

2017-03-31 00:00 351 查看
Set集合

Set是一个无序而且不重复的元素集合。下面看看他有哪些基本功能

创建集合

1
2
3
4
5
6
>>>s1={11,22}
s2=set()
s3=set([11,22,33,4])
print(s1,s2,s3)
-------------------
{11,22}set(){33,11,4,22}
把列表转换成集合,注意列表中重复的元素只保留一次

1
2
3
4
5
>>>li=[11,22,11,22]
s1=set(li)
print(s1)
---------------
{11,22}
add给集合添加元素,clear清除集合的内容

1
2
3
4
5
6
7
8
9
10
11
12
>>>s=set()
print(s)
s.add(123)
s.add(123)
s.add(123)
print(s)
s.clear()
print(s)
---------------
set()
{123}
set()
两个集合A和B可以通过difference进行比较,他会输出A中存在,而B中不存在的元素

1
2
3
4
5
6
7
8
9
10
>>>s1={11,22,33}
s2={22,33,44}
s3=s1.difference(s2)
print(s3)#A中存在,B中不存在
s3=s2.difference(s1)
print(s3)
--------------
{11}
{44}
symmetric_difference可以输出两个集合中都不相同的元素

1
2
3
4
5
6
7
8
>>>s3=s1.symmetric_difference(s2)
print(s1)
print(s2)
print(s3)
--------------
{33,11,22}
{33,44,22}
{11,44}
如果后面跟了update,那么他的作用是直接替换到A的结果中,比如A中存在,B中不存在的结果是11,difference_update直接替换了A的内容;类似的如果我再执行symmetric_difference_update,他把A和B都不相同的内容保存在A中。

1
2
3
4
5
6
7
>>>s1.difference_update(s2)
print(s1)
s1.symmetric_difference_update(s2)
print(s1)
------------
{11}
{33,11,44,22}
删除某一个元素可以用discard或者remove,但是如果该元素不存在,使用discard不会报错;而remove会抛出异常

1
2
3
4
5
>>>s1={11,22,33,1111}
s1.discard(1111)
print(s1)
----------
{33,11,22}
不报错

1
2
>>>s1={11,22,33,}
s1.discard(1111)
抛出异常

1
2
3
4
5
6
7
>>>s1={11,22,33,}
#s1.discard(1111)
s1.remove(11111)
--------------------
Traceback(mostrecentcalllast):
File"<input>",line3,in<module>
KeyError:11111
如果随机的删除一个元素,可以使用pop

1
2
3
4
5
6
>>>ret=s1.pop()##随机删
print(s1)
print(ret)
-------------
{11,22}
33
求交集(Intersection)和并集(Union)

1
2
3
4
5
6
7
8
9
10
>>>s1={11,22,33}
s2={22,33,44}
s3=s1.union(s2)
print(s3)
s3=s1.intersection(s2)
s1.intersection_update(s2)
print(s3)
-----------------
{33,22,11,44}
{33,22}
update可以把其他的列表,元祖或者字符串的元素都并集进来,当然重复的不会添加

1
2
3
4
5
6
7
8
9
10
11
12
13
>>>s1={11,22,33}
s1.add(11)
s1.add(12)
s1.add(13)
li=[11,22,3,11,2]
tup=(11,22,3,11,2)
st="alexalex"
s1.update(li)
s1.update(tup)
s1.update(st)
print(s1)
-----------------------
{33,2,3,'l','a',11,12,13,22,'x','e'}
小练习:两个字典,请判断出哪些key进行了变化,添加,删除和没变?

思路:把key单独转换成集合,然后通过判断集合元素是否存在判断添加和删除;通过交集判断哪些仍然存在为改变

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
>>>old_dict={
"#1":8,
"#2":4,
"#4":2,
}
new_dict={
"#1":4,
"#2":4,
"#3":2,
}
new_set=set(new_dict.keys())
old_set=set(old_dict.keys())
remove_set=old_set.difference(new_set)
add_set=new_set.difference(old_set)
update_set=old_set.intersection(new_set)
print(remove_set,add_set,update_set)
----------------------
{'#4'}{'#3'}{'#2','#1'}
文件的操作

打开文件的模式

r,只读模式【默认】

w,只写模式【不可读;不存在则创建;存在则清空内容;】

x,只写模式【不可读;不存在则创建,存在则报错】

a,追加模式【可读;不存在则创建;存在则只追加内容;】

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

r+,读写【可读,可写】最常用

w+,写读【可读,可写】清空之后再写,然后可以读之后写入的内容

x+,写读【可读,可写】

a+,写读【可读,可写】只能在末尾更改,无法灵活指定位置

"b"表示以字节的方式操作

rb或r+b

wb或w+b

xb或w+b

ab或a+b

文件相关的函数

fread()无参数,读取全部;有参数,有b,按照字节读;有参数,无b,按照字符读

tell(),获取当前位置(字节)

seek(),调到指定的位置(字节)

write(),写入数据,有b,按照字节;无b,按照字符写入

close(),关闭文件

fileno(),文件描述符,判断文件是否有变化

flush(),强制刷新到内容

readable(),判断是否可读

readline(),按行读

truncate(),截断,清空指针后面的内容

for循环

with自动关闭文件

下面看看具体的例子

以只读方式打开一个文件db,注意编码我指定为utf-8,在utf-8里面一个汉字等于3个字节;而在gbk里面,一个汉字占据2个字节。

1
2
3
4
5
6
7
8
>>>f=open('db','r',encoding="utf-8")
data=f.read()
print(data,type(data))
f.close()
------------------
sdf
aa
dddd<class'str'>
我用只读字节的方式打开文件

1
2
3
4
>>>f=open('db','rb')
data=f.read()
print(data,type(data))
b'sdf\r\naa\r\ndddd'<class'bytes'>
下面的操作会抛出异常,因为我用字节的方式打开文件,当我尝试用字符串写入的时候,格式不兼容

1
2
3
4
5
6
7
>>>f=open("db",'ab')
f.write("hello")
f.close()
--------------
3ff0
-
Traceback(mostrecentcalllast):
File"<input>",line2,in<module>
TypeError:abytes-likeobjectisrequired,not'str'
字节的方式添加信息

1
2
3
>>>f=open("db",'ab')
f.write(bytes("哈",encoding="utf-8"))
f.close()
结果如下

1
2
3
sdf
aa
dddd哈
以读写方式打开文件,指定只读取前2个字符,注意这里没有指定b,因此是按字符读取;否则按照字节读取;tell()可以获取当前指针的位置(字节)

1
2
3
4
5
6
>>>f=open("db",'r+',encoding="utf-8")
data=f.read(2)
print(data)
print(f.tell())#获取当前指针位置(字节)
sd
2
首先读取一个包含汉字的文件,如下所示,我指定了编码是utf-8,也指定了b,因此他是按照字符读取;这里他读取前2个字符“幸福”,然后因为utf-8一个汉字字符是3个字节,因此他的位置是6个字节处

1
2
3
4
5
6
7
>>>f=open("db",'r+',encoding="utf-8")
data=f.read(2)
print(data)
print(f.tell())
--------------
幸福
6
如果这个时候我对这个文件做个修改,seek指定位置为第一个字节处,然后向后覆盖7777,这个时候他会把汉字(3个字节)硬拆开,导致的结果就是乱码

1
2
3
4
>>>f.seek(1)
#当前指针位置开始向后面覆盖
f.write("7777")
f.close()
结果如下所示

1
2
3
7777sdf
aa
dddd哈
flush函数强行把内存的数据写入硬盘保存,尽管还没有close

1
2
3
4
>>>f=open('db','a')
f.write('123')
f.flush()#没有close但是内容写入了硬盘
input("hhhh")
readable顾名思义,判断一个文件是否可读,这里我一个只写方式打开的文件返回False

1
2
3
4
>>>f=open('db','w')
print(f.readable())
---------
False
read()是读取全部,read(x)是读取前x个字节或者字符,而readline()是读取一行,注意指针位置变化

1
2
3
f=open('db','r')
f.readline()#注意指针的变化
f.readline()
truncate截断,指针后面的内容清空

1
2
3
>>>f=open('db','r+',encoding='utf-8')
f.seek(3)
f.truncate()
结果如下

1
sds
一个很常见的方式是通过for循环来读取每一行的内容,如下所示

1
2
3
4
5
6
7
8
>>>f=open('db','r+',encoding='utf-8')
forlineinf:
print(line)
-------------
sds
2
234
232sd
with自动关闭文件,这样不需要手动的使用f.close()了

1
2
withopen('db')asf:
pass
Python2.7以后,可以同时操作两个文件,比如说,只读方式打开文件1,拷贝前10行文件到文件2里面

1
2
3
4
5
6
7
8
withopen('db1','r',encoding="utf-8")asf1,open('db2','w',encoding='utf-8')asf2:
times=0
forlineinf1:
times+=1
iftimes<=10:
f2.write(line)
else:
break
登录乐搏学院官网http://www.learnbo.com/

或关注我们的官方微博微信,还有更多惊喜哦~



本文出自“麻婆豆腐”博客,请务必保留此出处http://beanxyz.blog.51cto.com/5570417/1840946
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: