DAY2-python数据类型、字符编码、文件处理

 

阅读目录

一、引子

1 什么是数据?

  x=10,10是我们要存储的数据

2 为何数据要分不同的类型

  数据是用来表示状态的,不同的状态就应该用不同的类型的数据去表示

3 数据类型

  数字(整形,长整形,浮点型,复数)

  字符串

  字节串:在介绍字符编码时介绍字节bytes类型

  列表

  元组

  字典

  集合

二、数字

整数与浮点数

#整型int
  作用:年纪,等级,身份证号,qq号等整型数字相关
  定义:
    age=10 #本质age=int(10)

#浮点型float
  作用:薪资,身高,体重,体质参数等浮点数相关

    salary=3000.3 #本质salary=float(3000.3)

#二进制,十进制,八进制,十六进制

#二:该类型总结
1 存一个值or存多个值
    只能存一个值

2 无序

3 可变or不可变
    !!!不可变:值变,id就变。不可变==可hash
 

其他数字类型(了解)

#长整形(了解)
    在python2中(python3中没有长整形的概念):      
    >>> num=2L
    >>> type(num)
    <type 'long'>

#复数(了解)  
    >>> x=1-2j
    >>> x.real
    1.0
    >>> x.imag
    -2.0  

三、字符串

#作用:名字,性别,国籍,地址等描述信息

#定义:在单引号\双引号\三引号内,由一串字符组成
name='egon'

#二:该类型总结
1 存一个值or存多个值
    只能存一个值2 可变or不可变
    !!!不可变:值变,id就变。不可变==可hash

 优先掌握的操作:

#1、按索引取值(正向取+反向取) :只能取
msg='hello world'
#第一位从0开始,最后一位是-1,倒数第二位是-2。
print(msg[0],msg[-1]))
h d

#2、切片(顾头不顾尾,步长)
print(msg[0:3]) #>=0 <3
hel
#不写代表从头开始,取到最后一位,如果写-1,最后一位取不到
print(msg[:])
hello world
#设定步长为2,先取第一位,隔一位取一个;默认步长是1
print(msg[0:7:2]) 
hlow
#反向取值,注意,顾头不顾尾,所以6能取到,而1不能
print(msg[6:1:-1])
w oll
#将字符串反转
print(msg[-1::-1])
dlrow olleh

#3、长度len
print(len(msg))  #等同于,print(msg.__len__()),但是一般我们只用len()
11

#4、成员运算in和not in
print('llo' in msg)
True
print('llo' not in msg)
False

#5、移除strip(两边开始,中间不管,默认可移除空格、\n、\t)
password='    alex 3714     '
print(password.strip())
alex 3714
#指定移除的字符
password='***alex3714***'
print(password.strip('*'))
alex3714
#从左边移除
password='***alex3714***'
print(password.lstrip('*'))
alex3714***
#从右边移除
print(password.rstrip('*'))
***alex3714
#与input连用
password=input('>>: ').strip()

#6、切分split,默认按空格切分,切分结果存在列表中
user_info='root:x:0:0::/root:/bin/bash'
res=user_info.split(':')
print(res)
['root', 'x', '0', '0', '', '/root', '/bin/bash']
#指定从左向右,切割几次,默认切到结束
print(user_info.split(':',1))
['root', 'x:0:0::/root:/bin/bash']
#从右向左,切割几次,注意列表顺序还是从左向右的。
print(user_info.rsplit(':',1))
['root:x:0:0::/root', '/bin/bash']

#7、循环,把字符串每个字符遍历输出
msg='hel'
for i in msg:
    print(i)
h
e
l

msg='hel'
for i in range(len(msg)): #0 1 2
    print(i,msg[i])
0 h
1 e
2 l
#判断一个字符串是否为空
len('') == 0

字符串类型总结

#二:该类型总结
# 1 存一个值or存多个值
#     只能存一个值

# 2 有序

# 3 可变or不可变
#     !!!不可变:值变,id就变。不可变==可hash

 多变量赋值

# Assign values directly
a, b = 0, 1
  
# Assign values from a list
r,g,b =  ["Red","Green","Blue"]

# Assign values from a tuple
x,y = (1,2)
#链式赋值
a=b=c=2
print(id(a),id(b),id(c))
493143760 493143760 493143760

#交叉赋值
m=1
n=2
m,n=n,m
print(m,n)

#解压
l=[1,2,3,4]
a,b,c,d=l
print(a,b,c,d)
1 2 3 4

#用_作为占位符
l=[1,2,3,4]
a,_,_,d=l
print(a,d)

#可以使用*_表示多个
a,*_,d=l
print(a,d)
各种赋值

range

#renge(起始值,结束值,步长)
#用于获取指定范围内的数。
#在2.7中,使用range会创建所有数字,占用内存。xrange是默认不创建,只在for循环中,一个循环创建一个;3中range就等同于xrange,xrange也移除了。
#默认从0开始,顾头不顾尾
for i in range(3):
    print(i)
0
1
2
#指定开始值开始
for i in range(1,3,1):
    print(i)
1
2
#反向取值
for i in range(3,1,-1)
    print(i)
3
2
enumerate
#enumerate(列表或元祖,指定起始值)
#enumerate自动生成一列从0开始自增1的数字,通过for循环与列表或者元祖的每个元素组成新的元祖。

li = ['电脑','鼠标','游艇','U盘']
for key in enumerate(li):
    print(key)
(0, '电脑')
(1, '鼠标')
(2, '游艇')
(3, 'U盘')

#enumerate(li,1)生成从1开始自增1的数,注意虽然1对应电脑,但是取值的索引还是0。
li = ('电脑','鼠标','游艇','U盘')
for x,y in enumerate(li,1):
    print(x,y)
1 电脑
2 鼠标
3 游艇
4 U盘

        

 需要掌握的操作

#1、partition,rpartition
#指定分割符,将字符串分割成三部分,保存到元祖中,只分割一次
msg='hello word'
print(msg.partition('o'))
('hell', 'o', ' word')
#从又向左找分隔符
msg='hello word'
print(msg.rpartition('o'))
('hello w', 'o', 'rd')

#2、lower,upper
#将字符串大写
print('ALeX'.lower())
#将字符串小写
print('aaa'.upper())

#3、startswith,endswith
#0开始5结束是否以'a'开始
msg='alex is SB'
print(msg.startswith('a',0,5))
True
#字符串是否以B结尾
print(msg.endswith('B'))

#4、join
#将元素都是字符串的列表或元祖的每个元素以指定字符串拼接(注意这是字符串的功能)
li=['aa','bb','cc']
print('_'.join(li))
aa_bb_cc
#如果元素中有数字,就会报错

#5、replace
#将前面的内容替换成后面的内容,指定替换几次,默认全部替换
msg='alex say my name is alex ,alex have on tesla'
print(msg.replace('alex','SB',1))
SB say my name is alex ,alex have on tesla

#6、isdigit
#isdigit:可以判断bytes和unicode类型,是最常用的用于于判断字符是否为"数字"的方法
age=input('>>: ')
print(age.isdigit())

其他操作(了解即可)

#1、find,rfind,index,rindex,count
#find找到字符串所在索引,不存在返回-1
msg='hello world'
print(msg.find('wo'))
#rfind反方向开始找
#index,rindex找索引,不存在报错
print(msg.index('SB')) #ValueError: substring not found
#count,统计有多少个。
print(msg.count('l'))
print(msg.count('l',0,5))  #指定范围

#2、center,ljust,rjust,zfill
#center,居中,其余地方默认用空格填充
print('egon'.center(30,'*'))
#ljust,左对齐
print('egon'.ljust(30,'*'))
#rjust,右对齐
print('egon'.rjust(30,'*'))
#zfill,居右,用0填充
00000000000000000000000000egon

#3、expandtabs
#指定\t为几个字符
print('hello\tworld'.expandtabs(10))
hello     world

#4、captalize,swapcase,title
#captalize、将字符串首字母大写
print('i am egon'.capitalize())
I am egon
#swapcase、大小写反转
print('AbC'.swapcase())
#title、将每个单词首字母大写
print('i am egon'.title())

#5、is数字系列(不能判断浮点数)
num1=b'4' #bytes
num2=u'4' #unicode,python3中无需加u就是unicode
num3='' #中文数字
num4='' #罗马数字
isdigit()能识别:bytes,unicode的数字
isdecimal()能识别:unicode的数字
isnumeric()能识别:unicode,中文,罗马的数字

#6、is其他
# name='egon123'
# print(name.isalnum()) #字符串由字母或数字组成
# print(name.isalpha()) #字符串只由字母组成
# print('abcA'.islower())#判断都是小写
# print(name.isupper())#判断都是大写
# print(' '.isspace())#判断是不是空格(不是空)
# print('Am Ia'.istitle())#判断是不是标题
#判断字符串是否是合法的标识符,字符串仅包含中文字符合法
print('print1111'.isidentifier())
#实际上这#里判断的是变量名是否合法。如:
'_a'.isidentifier() -->True
'3a'.isidentifier() -->False
'中国'.isidentifier() -->True

注意:所有修改字符串的操作都是新生成一个字符串,而不是修复源字符串,因为字符串是不可变的。

四、列表

#作用:多个装备,多个爱好,多门课程,多个女朋友等

#定义:[]内可以有多个任意类型的值,逗号分隔
my_girl_friends=['alex','wupeiqi','yuanhao',4,5] #本质my_girl_friends=list([...])
或
l=list('abc')

优先掌握的操作:
1、按索引存取值(正向存取+反向存取):即可存也可以取 

#取值与字符串操作一样
#对其中元素从新赋值,就是改变原列表
my_girl_friends=['alex','wupeiqi','yuanhao',4,5]
print(my_girl_friends[1])
my_girl_friends[1]='bbb'
print(my_girl_friends)

wupeiqi
['alex', 'bbb', 'yuanhao', 4, 5]

2、切片(顾头不顾尾,步长)

#与列表操作一致
#ps:反向步长
l=[1,2,3,4,5,6]

#正向步长
l[0:3:1] #[1, 2, 3]
#反向步长
l[2::-1] #[3, 2, 1]
#列表翻转
l[::-1] #[6, 5, 4, 3, 2, 1]

3、长度len(元素个数)

#实际上也是在调用__len__()
print(my_girl_friends.__len__())
print(len(my_girl_friends))

4、成员运算in和not in

print('wupeiqi' in my_girl_friends)
True

5、追加append

#列表不能通过定义新索引来追加,会报错
my_girl_friends=['alex','wupeiqi','yuanhao',4,5]
my_girl_friends[5]=3 #IndexError: list assignment index out of range
my_girl_friends.append(6)
print(my_girl_friends)
['alex', 'wupeiqi', 'yuanhao', 4, 5, 6]

6、删除del、remove、pop

my_girl_friends=['alex','wupeiqi','yuanhao',4,5]
#1、单纯的删除、不能把删除的值赋给其他变量
del my_girl_friends[0]
print(my_girl_friends)
['wupeiqi', 'yuanhao', 4, 5]

res=my_girl_friends.remove('yuanhao')
print(my_girl_friends)
print(res)
['alex', 'wupeiqi', 4, 5]
None

#2、删除并拿到结果:取走一个值,指定索引,不指定从最后一个开始
res=my_girl_friends.pop(2)
print(my_girl_friends)
print(res)
['alex', 'wupeiqi', 4, 5]
yuanhao

my_girl_friends=['alex','wupeiqi','yuanhao',4,5]
print(my_girl_friends.pop(0)) #'alex'
print(my_girl_friends.pop(0)) #'wupeqi'
print(my_girl_friends.pop(0)) #'yuanhao'

7、循环

#每次循环得到一个元素
my_girl_friends=['alex','wupeiqi','yuanhao',4,5]
for i in my_girl_friends:
    print(i)

要掌握的方法:

1、插入insert

my_girl_friends=['alex','wupeiqi','yuanhao','yuanhao',4,5]
my_girl_friends.insert(1,'egon')
print(my_girl_friends)
['alex', 'egon', 'wupeiqi', 'yuanhao', 'yuanhao', 4, 5]

2、清除clear

my_girl_friends=['alex','wupeiqi','yuanhao','yuanhao',4,5]
my_girl_friends.clear()
print(my_girl_friends)
[]

3、统计count

my_girl_friends=['alex','wupeiqi','yuanhao','yuanhao',4,5]
print(my_girl_friends.count('yuanhao'))
2

4、拷贝copy

my_girl_friends=['alex','wupeiqi','yuanhao','yuanhao',4,5]
l=my_girl_friends.copy()
print(l)
['alex', 'wupeiqi', 'yuanhao', 'yuanhao', 4, 5]

5、扩展extend

#append和insert都只能加入一个值,extend的可以添加多个
#字符串、列表,元祖,字典等可for循环的,都可以被extend
my_girl_friends=['alex','wupeiqi','yuanhao','yuanhao',4,5]
l=['egon1','egon2']
my_girl_friends.extend(l)
my_girl_friends.extend('hello')

6、取索引index

my_girl_friends=['alex','wupeiqi','yuanhao','yuanhao',4,5]
print(my_girl_friends.index('wupeiqi'))
print(my_girl_friends.index('wupeiqissssss'))
#不存在报错ValueError: 'wupeiqissssss' is not in list

7、反转列表reverse

my_girl_friends=['alex','wupeiqi','yuanhao','yuanhao',4,5]
my_girl_friends.reverse()
print(my_girl_friends)
[5, 4, 'yuanhao', 'yuanhao', 'wupeiqi', 'alex']

8、列表排序sort

#正向排序
l=[1,10,4,11,2]
l.sort()
print(l)
[1, 2, 4, 10, 11]

#反向排序
l.sort(reverse=True)
print(l)
[11, 10, 4, 2, 1]

#注意:
#字符串排序是从左向右一个一个比对,按照ascii的顺序比对
#列表只能是纯数字或者纯字符串才能排序,否则报错
#二:该类型总结
# 1 存一个值or存多个值
#     可以存多个值,值都可以是任意类型

# 2 有序

# 3 可变or不可变
#     !!!可变:值变,id不变。可变==不可hash

注意:所有修改列表的操作都是直接操作源列表的。

 五、元祖

#作用:存多个值,对比列表来说,元组不可变(是可以当做字典的key的),主要是用来读,如果元祖元素是列表或者字典,则列表或字典的元素是可以变的。

#定义:与列表类型比,只不过[]换成()
age=(11,22,33,44,55)本质age=tuple((11,22,33,44,55))

#优先掌握的操作:
#1、按索引取值(正向取+反向取):只能取   
#2、切片(顾头不顾尾,步长)
#3、长度
#4、成员运算in和not in
#5、循环
#与列表都一样

需要掌握的内容

#1、查找索引 index
age=(11,22,33,44,55)
print(age.index(33))
print(age.index(33333))  #不存在报错

#2、统计count
print(age.count(33))
#二:该类型总结
# 1 存一个值or存多个值
#     可以存多个值,值都可以是任意类型

# 2 有序

# 3 可变or不可变
#     !!!不可变:值变,id就变。不可变==可hash

六、字典

#作用:存多个值,key-value存取,取值速度快

#定义:key必须是不可变类型,value可以是任意类型
info={'name':'egon','age':18,'sex':'male'} #本质info=dict({....})
或
info=dict(name='egon',age=18,sex='male')
或
info=dict([['name','egon'],('age',18)])
或 
{}.fromkeys(('name','age','sex'),None)   #除了元祖还可以是列表,字符串等可迭代的数据,然后每个键都赋值为None,可以批量创建键值对
#fromkeys()的定义:
        def fromkeys(*args, **kwargs):  # 将所有key都赋予相同的值,第一参数为key,第二个参数为value,如果没有第二个参数则默认为none;
#注意!!!是将所有key都赋予同一个值,比如如果value是一个[],则所有value指向的内存地址是同一个地址,也就是说往一个key的[]中append一个数据,则所有key的[]都被append了一个同样的数据,因为所有[]是同一个内存地址。

#如果想让value不一样, 可以这样:
test = {}
for i in range(10):
    test[i] = []
fromkeys()的坑

 

优先掌握的内容

#1、按key存取值:可存可取
可通过赋值一个不存在的key,来增加新的键值对。
d={'name':'egon'}
print(d['name'])
d['age']=18
print(d)

#2、长度len,键值对个数
info={'name':'egon','age':18,'sex':'male'}
print(len(info))
3

#3、成员运算in和not in,针对key的,而不是值value
info={'name':'egon','age':18,'sex':'male'}
print('name' in info)
True
print('egon' in info)
False

#4、删除
#pop,移除指定键值对,并得到value
info={'name':'egon','age':18,'sex':'male'}
print(info.pop('name'))
print(info)
egon
{'age': 18, 'sex': 'male'}
#key不存在会报错,可指定不存在的key返回值而不报错。
print(info.pop('name111',None))
None

#popitem,删除最后一个键值对(尽量当做无序的),得到键值对
info={'name':'egon','age':18,'sex':'male'}
print(info.popitem()) 
('sex', 'male')

#5、键keys(),值values(),键值对items() #了解
print(info.keys()) #打印所有键
print(list(info.keys())[0]) #转换成列表取元素
print(list(info.values())) #打印所有值
print(list(info.items())) #打印所有键值对

#6、循环
#默认是对key进行循环
info={'name':'egon','age':18,'sex':'male'}
for k in info:
    print(k,info[k])
for v in info.values():
    print(v)

需要掌握的内容

#1、取值get
info={'name':'egon','age':18,'sex':'male'}
print(info['hobbies'])     #取不存在的key报错退出
print(info.get('hobbies')) #使用get不会报错
None
print(info.get('hobbies','没有')) #指定返回值

#2、update 、把一个字典加入另一个字典
info={'name':'egon','age':18,'sex':'male'}
d={'x':1,'y':2,'name':'EGON'}
info.update(d)
print(info)
{'name': 'EGON', 'age': 18, 'sex': 'male', 'x': 1, 'y': 2}

#3、setdefault,如果key存在,则不修改,返回已经有的key对应的value
info={'name':'egon','age':16,'sex':'male'}
value=info.setdefault('age',18) 
print(value)
print(info)
16
{'name': 'egon', 'age': 16, 'sex': 'male'}
#如果key不存在,则新加一个键值对
info={'name':'egon','age':16,'sex':'male'}
hobbies_list=info.setdefault('hobbies',[])
print(hobbies_list)
hobbies_list.append('play')
hobbies_list.append('read')
print(info)
[]
{'name': 'egon', 'age': 16, 'sex': 'male', 'hobbies': ['play', 'read']}
#二:该类型总结
# 1 存一个值or存多个值
#     可以存多个值,值都可以是任意类型,key必须是不可变类型
#
# 2 无序

# 3 可变or不可变
#     !!!可变:值变,id不变。可变==不可hash

练习:

统计s='hello alex alex say hello sb sb'中每个单词的个数

结果如:{'hello': 2, 'alex': 2, 'say': 1, 'sb': 2}
#利用setdefault解决重复赋值
'''
setdefault的功能
1:key存在,则不赋值,key不存在则设置默认值
2:key存在,返回的是key对应的已有的值,key不存在,返回的则是要设置的默认值
d={}
print(d.setdefault('a',1)) #返回1

d={'a':2222}
print(d.setdefault('a',1)) #返回2222
'''
s='hello alex alex say hello sb sb'
dic={}
words=s.split()
for word in words: #word='alex'
    dic.setdefault(word,s.count(word))
    print(dic)
View Code

七、集合

#作用:去重,关系运算,

#定义:
            可变类型是不可hash类型

#定义集合:
            集合:可以包含多个元素,用逗号分割,
            集合的元素遵循三个原则:
             1:每个元素必须是不可变类型(可hash,可作为字典的key)
             2:没有重复的元素
             3:无序

注意集合的目的是将不同的值存放到一起,不同的集合间用来做关系运算,无需纠结于集合中单个值

优先掌握内容

#优先掌握的操作:
#1、定义集合:{}内用逗号分割每个元素都必须是不可变类型,元素不能重复,无序
s={1,2,3,1} #s=set({1,2,3,1})

#1、长度len
print(len(s))

#2、成员运算in和not in
names={'egon','alex'}
print('egon' in names)
pythons={'egon','axx','ysb','wxx'}
linuxs={'egon','oldboy','oldgirl','smallboy','smallgirl'}

#3、|合集:老男孩所有的学生
print(pythons | linuxs)
print(pythons.union(linuxs))

#4、&交集:同时报名两门课程的学生
print(pythons & linuxs)
print(pythons.intersection(linuxs))

#5.1、-差集:只报名python课程的学生
print(pythons - linuxs)
print(pythons.difference(linuxs))

#5.2、-差集:只报名linux课程的学生
print(linuxs-pythons)
print(linuxs.difference(pythons))

#6、^对称差集:没有同时报名两门课程
print(pythons ^ linuxs)
print(pythons.symmetric_difference(linuxs))
#7、==
s1={1,2}
s2={1,2}
print(s1 == s2)
True
#8、父集:>,>= print(s1 >= s2) print(s1.issuperset(s2)) #9、子集:<,<= print(s2 <= s1) print(s2.issubset(s1))
#10、循环
linuxs={'egon','oldboy','oldgirl','smallboy','smallgirl'}
for student in linuxs:
    print(student)

了解的知识点

#1、pop随机取走
s2={1,2,3,4,5,'a'}
print(s2.pop())
print(s2)
1
{2, 3, 4, 5, 'a'}

#2、add添加
s2={1,2,3,4,5,'a'}
s2.add('b')
print(s2)
{1, 2, 3, 4, 5, 'a', 'b'}

#3、删除
#discard删除不存在的元素不报错
s2={1,2,3,4,5,'a'}
s2.discard('b')

#remove删除不存在的元素报错
s2={1,2,3,4,5,'a'}
s2.remove('b')

#4、isdisjoint两个集合没有共同部分时,返回值为True
s1={1,2,3,4,5,'a'}
s2={'b','c',}
print(s1.isdisjoint(s2))
True

#5、把可迭代的数据转换成集合
# l=['a','b',1,'a','a']
# print(list(set(l)))
# print(set('hello'))
# print(set({'a':1,'b':2,'c':3}))

#6、把差集从新赋值给集合
s1={1,2,3}
s2={1,2,}
print(s1-s2)
print(s1.difference(s2))
s1.difference_update(s2) #s1=s1.difference(s2)
print(s1)
{3}
{3}
{3}
二.去重

   1. 有列表l=['a','b',1,'a','a'],列表元素均为可hash类型,去重,得到新列表,且新列表无需保持列表原来的顺序

   2.在上题的基础上,保存列表原来的顺序

   3.去除文件中重复的行,肯定要保持文件内容的顺序不变
   4.有如下列表,列表元素为不可hash类型,去重,得到新列表,且新列表一定要保持列表原来的顺序

l=[
    {'name':'egon','age':18,'sex':'male'},
    {'name':'alex','age':73,'sex':'male'},
    {'name':'egon','age':20,'sex':'female'},
    {'name':'egon','age':18,'sex':'male'},
    {'name':'egon','age':18,'sex':'male'},
]  
#去重,无需保持原来的顺序
l=['a','b',1,'a','a']
print(set(l))

#去重,并保持原来的顺序
#方法一:不用集合
l=[1,'a','b',1,'a']

l1=[]
for i in l:
    if i not in l1:
        l1.append(i)
print(l1)
#方法二:借助集合
l1=[]
s=set()
for i in l:
    if i not in s:
        s.add(i)
        l1.append(i)

print(l1)


#同上方法二,去除文件中重复的行
import os
with open('db.txt','r',encoding='utf-8') as read_f,\
        open('.db.txt.swap','w',encoding='utf-8') as write_f:
    s=set()
    for line in read_f:
        if line not in s:
            s.add(line)
            write_f.write(line)
os.remove('db.txt')
os.rename('.db.txt.swap','db.txt')

#列表中元素为可变类型时,去重,并且保持原来顺序
l=[
    {'name':'egon','age':18,'sex':'male'},
    {'name':'alex','age':73,'sex':'male'},
    {'name':'egon','age':20,'sex':'female'},
    {'name':'egon','age':18,'sex':'male'},
    {'name':'egon','age':18,'sex':'male'},
]
# print(set(l)) #报错:unhashable type: 'dict'
s=set()
l1=[]
for item in l:
    val=(item['name'],item['age'],item['sex'])
    if val not in s:
        s.add(val)
        l1.append(item)

print(l1)






#定义函数,既可以针对可以hash类型又可以针对不可hash类型
def func(items,key=None):
    s=set()
    for item in items:
        val=item if key is None else key(item)
        if val not in s:
            s.add(val)
            yield item

print(list(func(l,key=lambda dic:(dic['name'],dic['age'],dic['sex']))))
View Code

八、数据类型总结

按存储空间的占用分(从低到高)

数字
字符串
集合:无序,即无序存索引相关信息
元组:有序,需要存索引相关信息,不可变
列表:有序,需要存索引相关信息,可变,需要处理数据的增删改
字典:无序,需要存key与value映射的相关信息,可变,需要处理数据的增删改

按存值个数区分

标量/原子类型数字,字符串
容器类型列表,元组,字典

 

 

按可变不可变区分

可变列表,字典
不可变数字,字符串,元组

 

 

按访问顺序区分

直接访问数字
顺序访问(序列类型)字符串,列表,元组
key值访问(映射类型)字典

 

 

  

九、运算符

详细:http://www.cnblogs.com/linhaifeng/articles/5935801.html#_label34

十、字符编码

1、存取文件不乱码的法则:用什么编码存的,就要用什么编码读
2、
    unicode-----encode----->gbk           (编码)
    gbk-------->decode----->unicode      (解码)

3、
    python3解释器默认使用的字符编码是utf-8
    python2解释器默认使用的字符编码是ascii
    内存中使用的是unicode
4
    python2的str就是python3的bytes
    python2的unicode就是python3的str

详细:http://www.cnblogs.com/linhaifeng/articles/5950339.html

十一、文件处理

一、文件操作

1、操作文件的流程

#1. 打开文件,得到文件句柄并赋值给一个变量
f=open('a.txt','r',encoding='utf-8') #默认打开模式就为r

#2. 通过句柄对文件进行操作
data=f.read()

#3. 关闭文件
f.close()

2、 f=open('a.txt','r')的过程分析

#1、由应用程序向操作系统发起系统调用open(...)

#2、操作系统打开该文件,并返回一个文件句柄给应用程序

#3、应用程序将文件句柄赋值给变量f

注意!!!:

#强调第一点:
打开一个文件包含两部分资源:操作系统级打开的文件+应用程序的变量。在操作完毕一个文件时,必须把与该文件的这两部分资源一个不落地回收,回收方法为:
1、f.close() #回收操作系统级打开的文件
2、del f #回收应用程序级的变量

其中del f一定要发生在f.close()之后,否则就会导致操作系统打开的文件还没有关闭,白白占用资源,
而python自动的垃圾回收机制决定了我们无需考虑del f,这就要求我们,在操作完毕文件后,一定要记住f.close()

我们推荐傻瓜式操作方式:使用with关键字来帮我们管理上下文,不需要自己调用close
with open('a.txt','w') as f:
    pass
 
with open('a.txt','r') as read_f,open('b.txt','w') as write_f:
    data=read_f.read()
    write_f.write(data)
1、关闭文件
#强调第二点:
f=open(...)是由操作系统打开文件,那么如果我们没有为open指定编码,那么打开文件的默认编码很明显是操作系统说了算了,操作系统会用自己的默认编码去打开文件,在windows下是gbk,在linux下是utf-8。
这就用到了上节课讲的字符编码的知识:若要保证不乱码,文件以什么方式存的,就要以什么方式打开。

f=open('a.txt','r',encoding='utf-8')
2、字符编码

3、python2中的file与open

#首先在python3中操作文件只有一种选择,那就是open()

#而在python2中则有两种方式:file()与open()
两者都能够打开文件,对文件进行操作,也具有相似的用法和参数,但是,这两种文件打开方式有本质的区别,file为文件类,用file()来打开文件,相当于这是在构造文件类,而用open()打开文件,是用python的内建函数来操作,我们一般使用open()打开文件进行操作,而用file当做一个类型,比如type(f) is file
View Code
二、打开文件的模式
文件句柄 = open('文件路径', '模式')

模式可以是以下方式以及他们之间的组合:

CharacterMeaning
‘r'open for reading (default)
‘w'open for writing, truncating the file first
‘a'open for writing, appending to the end of the file if it exists
‘b'binary mode
‘t'text mode (default)
‘+'open a disk file for updating (reading and writing)
‘U'universal newline mode (for backwards compatibility; should not be used in new code)

#1. 打开文件的模式有(默认为文本模式): r ,只读模式【默认模式,文件必须存在,不存在则抛出异常】 w,只写模式【不可读;不存在则创建;存在则清空内容】 a, 之追加写模式【不可读;不存在则创建;存在则只追加内容;注意:a模式打开文件首先把光标移动到最后】 #2. 对于非文本文件,我们只能使用b模式,"b"表示以字节的方式操作(而所有文件也都是以字节的形式存储的,使用这种模式无需考虑文本文件的字符编码、图片文件的jgp格式、视频文件的avi格式) rb wb ab 注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型,不能指定编码 #3. 了解部分 "+" 表示可以同时读写某个文件 r+, 读写【可读,可写】 w+,写读【可读,可写】 a+, 写读【可读,可写】 x, 只写模式【不可读;不存在则创建,存在则报错】 x+ ,写读【可读,可写】 xb
三、操作文件的方法
a b
c d
#掌握
f.read() #读取所有内容,存放到字符串中,光标移动到文件末尾
a b
c d
f.readline() #读取一行内容,存放到字符串在,光标移动到第二行首部
a b
f.readlines() #读取每一行内容,存放于列表中,注意有换行符
['a b\n', 'c d']

f.write('1111\n222\n') #针对文本模式的写,需要自己写换行符,只能是单个字符串
f.write('1111\n222\n'.encode('utf-8')) #针对b模式的写,需要自己写换行符
f.writelines(['333\n','444\n']) #文件模式,可以把列表写入文件
f.writelines([bytes('333\n',encoding='utf-8'),'444\n'.encode('utf-8')]) #b模式

#了解
f.readable() #文件是否可读
f.writable() #文件是否可读
f.closed #文件是否关闭
f.encoding #如果文件打开模式为b,则没有该属性
f.flush() #立刻将文件内容从内存刷到硬盘
f.name
四、文件内光标移动

一: read(3):

  1. 文件打开方式为文本模式时,代表读取3个字符(只有这种模式时光标是以字符移动的)

with open('c.txt','rt',encoding='utf-8') as f:
    print(f.read(6))
    print(f.tell())

 

  2. 文件打开方式为b模式时,代表读取3个字节

with open('c.txt','rb') as f:
    print(f.read(6))
    f.seek(2,1)
    print(f.tell())
    print(f.read().decode('utf-8'))

 

二: 其余的文件内光标移动都是以字节为单位如seek,tell,truncate

注意:

  1. seek有三种移动方式0,1,2,其中1和2必须在b模式下进行,但无论哪种模式,都是以bytes为单位移动的

    0模式:以文件最开始为参照,f.seek(6,0) 将光标从文件最开始向后移动6个字节

    1模式:以当前位置为参照,f.seek(6,1) 将光标从当前位置向后移动6个字节;f.seek(-6,1)将光标从当前位置向前移动6个字节

    2模式:以文件最末为参照,f.seek(0,2)将光标移动到文件最后;f.seek(-6,2)将光标从最后向前移动6个字节

  2.tell获取当前文件读取指针的位置:print(f.tell())

  3. truncate是截断文件,所以文件的打开方式必须可写,但是不能用w或w+等方式打开,因为那样直接清空文件了,所以truncate要在r+或a或a+等模式下测试效果

   如果指定了可选参数 size,则表示截断文件为 size 个字节。 如果没有指定 size,则从当前位置起截断;截断之后 size 后面的所有字符被删除。   

with open('access.log','a',encoding='utf-8') as f:
    f.truncate(3)

 

import time
with open('test.txt','rb') as f:
    f.seek(0,2)
    while True:
        line=f.readline()
        if line:
            print(line.decode('utf-8'))
        else:
            time.sleep(0.2)
练习:基于seek实现tail -f功能
五、文件的修改

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

方式一:将硬盘存放的该文件的内容全部加载到内存,在内存中是可以修改的,修改完毕后,再由内存覆盖到硬盘(word,vim,nodpad++等编辑器)

import os

with open('a.txt') as read_f,open('.a.txt.swap','w') as write_f:
    data=read_f.read() #全部读入内存,如果文件很大,会很卡
    data=data.replace('alex','SB') #在内存中完成修改

    write_f.write(data) #一次性写入新文件

os.remove('a.txt')
os.rename('.a.txt.swap','a.txt') 

方式二:将硬盘存放的该文件的内容一行一行地读入内存,修改完毕就写入新文件,最后用新文件覆盖源文件

import os

with open('a.txt') as read_f,open('.a.txt.swap','w') as write_f:
    for line in read_f:
        line=line.replace('alex','SB')
        write_f.write(line)

os.remove('a.txt')
os.rename('.a.txt.swap','a.txt') 

 

转载于:https://www.cnblogs.com/guoyunlong666/p/8018584.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值