一、字符串操作
1、index #返回字符串的索引值
s = "Hello word"
print(s.index('o'))
2、isalnum #检测字符串是否由字母和数字组成。
>>> '22d'.isalnum()
True
>>> '22'.isalnum()
True
3、isalpha #检测字符串是否只由字母组成。
>>> "c".isalpha()
True
>>> '1'.isalpha()
False
4、isdecimal #判断是否为整数 和isdigit效果一样
检查字符串是否只包含十进制字符。这种方法只存在于unicode对象。
注意:定义一个十进制字符串,只需要在字符串前添加 'u' 前缀即可。
>>> '1'.isdecimal()
True
>>> '22.2'.isdecimal()
False
5、isidentifier #判断字符串是否为一个合法的变量
>>> '33'.isidentifier()
False
>>> 'a1121'.isidentifier()
True
6、islower #是否为小写
'132312dsada'.islower()
True
'AS122'.islower()
False
7、isnumeric #判断是否为一个整数
>>> '1'.isnumeric()
True
>>>'1.11'.isnumeric()
False
8、 isprintable #判断是否可以打印
9、isspace #判断是否为空格
10、istitle #判断首字符为大写
>>> s.istitle()
True
11、 join #将列表转换为字符串 可以选择以什么来区分列表里面的元素
>>> a =['a','b','c']
>>> '--'.join(a)
'a--b--c'
12、ljust #从右边判断长度如果长度不够用 指定的字符补全
>>> s.ljust(20,'-')
'Hello Word----------'
13、 lower #全部变小写
>>> s
'Hello Word'
>>> s.lower()
'hello word'
14、 upper #全部变大写
>>> s
'Hello Word'
>>> s.upper()
'HELLO WORD'
15、 strip #脱掉空格、换行和tab (lstrip只脱左边不脱右边,rstrip相反只脱右边不脱左边)
>>> s = '\n Hello Word '
>>> s
'\n Hello Word '
>>> s.strip()
'Hello Word'
16、 maketrans #用于创建字符映射的转换表,对于接受两个参数的最简单的调用方式,第一个参数是字符串,表示需要转换的字符,第二个参数也是字符串表示转换的目标。
两个字符串的长度必须相同,为一一对应的关系
translate 翻译表,先创建密码表,再翻译
>>> str_in = 'abcdef'
>>> str_out = '!@#$%^'
>>> table = str.maketrans(str_in,str_out)
{97: 33, 98: 64, 99: 35, 100: 36, 101: 37, 102: 94}# 对应关系表,这里的编号对应的是ascll 表的编号
>>> s
'\n Hello Word '
>>> s.translate(table)
'\n H%llo Wor$ '
17、replace #替换
>>> s.replace('o','O') #后面可以跟参数替换次数
'HellO WOrd'
18、rfind #找最右边的值 find是从左边找第一个值
>>> s.rfind('o')
7
>>> s.find('o')
4
>>> s
'Hello Word'
19、rindex #从右边开始找索引,如果找不到则报错
>>> s.rindex('o')
7
>>> s.rindex('sa')
Traceback (most recent call last):
20、 split #将字符串的选中的字符转换为列表,选中的字符为分割。
rsplit # s.rspit('o'1) #从右边开始分 可以指定分的次数
>>> s
'Hello Word'
>>>
>>> s.split('o')
['Hell', ' W', 'rd']
21、splitlines #以空格 换行 来分成列表
22、startswith #判断是否以什么开头
>>> s
'Hello Word'
>>> s.startswith("H")
True
23、 endswith #判断 是否以什么结尾
>>> s.endswith("rd")
True
#注意常用的必会
isdigit #方法检测字符串是否只由数字组成。
format # 一种格式化字符串的函数 str.format(),它增强了字符串格式化的功能。基本语法是通过 {} 和 : 来代替以前的 % 。
replace #把字符串中的 old(旧字符串) 替换成 new(新字符串),如果指定第三个参数max,则替换不超过 max 次。
find #检测字符串中是否包含子字符串 str ,如果指定 beg(开始) 和 end(结束) 范围,则检查是否包含在指定范围内,如果包含子字符串返回开始的索引值,否则返回-1。
count #统计字符串里某个字符出现的次数。可选参数为在字符串搜索的开始与结束位置
strip #用于移除字符串头尾指定的字符(默认为空格)。
center # 返回一个原字符串居中,并使用空格填充至长度 width 的新字符串。默认填充字符为空格。
split #通过指定分隔符对字符串进行切片,如果参数num 有指定值,则仅分隔 num 个子字符串
join #方法用于将序列中的元素以指定的字符连接生成一个新的字符串。
二、拷贝
1、浅copy
浅拷贝(copy):拷贝父对象,不会拷贝对象的内部的子对象。
names =['a','b','c','d',[1,2,3]] n2 = names.copy() # 通过copy 函数 创建一个新的列表 n2 names[1] = 'B' #将names列表 元素b 进行替换为B print(names) print(n2) #打印值发现 元素值并未改变,可以得出结论为copy只是将变量指向到同一内存地址 names[-1][0] = '9' #修改子列表1 为9 print(names) print(n2)# 打印发现 子列表值跟随 names值而变,得出结论变量名是指定了小列表的内存地址,也就是浅拷贝只能复制第一层 print(id(names[2])) print(id(n2[2]))
2、深copy
深拷贝(deepcopy): copy 模块的 deepcopy 方法,完全拷贝了父对象及其子对象。
import copy #导入copy工具箱 names =['a','b','c','d',[1,2,3]] n2 = copy.deepcopy(names) #使用深copy names[1] = 'B' #将names列表 元素b 进行替换为B print(names) print(n2) #打印值发现 元素值并未改变,可以得出结论为copy只是将变量指向到同一内存地址 names[-1][0] = '9' #修改子列表1 为9 print(names) print(n2)# 打印发现 深copy 所有元素均为独立元素 都可单独修改 print(id(names[2])) print(id(n2[2])) #深copy 一般很少用,因为在原有基础上又开辟一块内存空间,很浪费资源
三、元祖
元祖跟列表差不多,也是存一组数据,但是创建之后,便不能再修改,所以又叫只读列表
特性:
不可变
元祖本身不可变,如果元祖中还包含有其他可变元素,这些可变元素可以改变
功能:
index
count
切片
使用场景:
显示告诉别人,此处数据不可修改
数据库等配置信息等
s = (1,2,3,4,5,1,['A','B'])
print(s.index(1))#index
print(s.count(1))# count
print(s[1:])#切片
s[-1][0] = 'a' # 将列表A改成a
print (s)
输出结果
四、Hash
Hash,一般被翻译成“散列”,也有直接音译"哈希"的,就是把任意长度的输入,通过哈希算法,变换成固定长度的输出,输出的结果就叫做哈希值,这是一种压缩映射,也就是说一般哈希值的空间要小于输入空间,不同的输入但是得出的哈希值可能是相同的,所以不可能从哈希值来确定输入值,简单来说哈希就是将任意长度压缩为固定长度的函数。
1、特性
Hash的值计算过程中是依据输入值的一些特性计算的,这就要求Hash值必须固定,因此被Hash的值必须是不可变的,如字符串、数字、元祖。不可为列表
2、用途
-
文件签名
- MD5加密
- 密码验证
五、字典
简介
字典是一种key -value的数据类型,通过key的值来获取value
1、基本语法
info = { #大括号 'a':1,#用冒号隔断key value 'b':2, 'c':3 } print(info)
2、特性
- key -value 结构
- key必须可哈希、且必须为不可变数据类型、必须唯一
- 可存任意多个值、可修改、可不唯一
- 无序
- 查找速度快
3、基本操作
增加
info = { #大括号 'a':1,#用冒号隔断key 和 value 'b':2, 'c':3 } info['d'] = ['4','5'] #可以增加列表 print(info) # 结果 {'a': 1, 'b': 2, 'c': 3, 'd': ['4', '5']}
删除
info = { 'a':1, 'b':2, 'c':3 } info.pop("a")#删除字典给定键 key 所对应的值,返回值为被删除的值。key值必须给出。 否则,返回default值。 print(info) #输出 {'b': 2, 'c': 3} #del删除 del info["a"] print(info) #输出 {'b': 2, 'c': 3} info.popitem() #随机删除key的值 print(info) #输出 {'b': 2, 'c': 3}
清空
info.clear() #清空字典
print(info)
#输出
{}
info = { 'a':1, 'b':2, 'c':3 } info['a'] = 11 print(info) #结果{'a': 11, 'b': 2, 'c': 3}
查找 in or get
info = { 'a':1, 'b':2, 'c':3 } print("a" in info) #输出 True info = { 'a':1, 'b':2, 'c':3 } print("x" in info) #输出 False info = { 'a':1, 'b':2, 'c':3 } print (info['x']) #如果取得键字典里面没有就会报错 #报错
get
info = { 'a':1, 'b':2, 'c':3 } print (info.get('a')) #输出 1 info = { 'a':1, 'b':2, 'c':3 } print (info.get('a')) #如果取得键字典里面没有也不会报错则会返回 None #输出 None
两种方法都可以满足查找的要求,但是建议使用get因为get查找的值如果不存在不会报错!
多级字典嵌套
字典里可以套字典,一层一层这个意思
info = { 'a':{ 'A':1, 'B':2 }, 'b':2, 'c':3 } print(info) #输出 {'a': {'A': 1, 'B': 2}, 'b': 2, 'c': 3}
values #以列表返回一个字典所有的值
{'a': 1, 'b': 2, 'c': 3} >>> info.values() dict_values([1, 2, 3])
keys#以列表返回一个字典所有的键
>>> info.keys() dict_keys(['a', 'b', 'c'])
get
get() 函数返回指定键的值,如果值不在字典中返回默认值。
dict = {'Name': 'Zara', 'Age': 27} print "Value : %s" % dict.get('Age') print "Value : %s" % dict.get('Sex', "Never") #输出 Value : 27 Value : Never
setdefault
如果键不存在于字典中,将会添加键并将值设为默认值。
>>> info.setdefault('xiaoze','baliya') 'maliya' >>> info {'a': 1, 'b': 2, 'c': 3, 'xiaoze': 'maliya'}
update#把字典dict2的键/值对更新到dict里。
>>> info {'a': 1, 'b': 2, 'c': 3, 'xiaoze': 'baliya'} >>> info_2 {'A': 1, 'b': 2, 'c': [4, 5, 6]} >>> info.update(info_2) >>> info {'a': 1, 'b': 2, 'c': [4, 5, 6], 'xiaoze': 'baliya', 'A': 1}
items#以列表返回可遍历的(键, 值) 元组数组。
>>> info.items() dict_items([('a', 1), ('b', 2), ('c', [4, 5, 6]), ('xiaoze', 'baliya'), ('A', 1)])
fromkeys#用于创建一个新字典,以序列seq中元素做字典的键,value为字典所有键对应的初始值
>>> dict.fromkeys([1,2,3],'test') {1: 'test', 2: 'test', 3: 'test'}
循环操作
#方式一
info = { 'a':1, 'b':2, 'c':3 } for key in info: print(key,info[key]) #输出 a 1 b 2 c 3
#方式二
for key,y in info.items(): print(key,y) #输出 a 1 b 2 c 3
#使用第一种方法不是建议,第二种方法刚刚说过了是将字典转换为列表然后在循环打印,这样大大降低了效率!
字典练习题
dic = { 'k1':'v1', 'k2':'v2', 'k3':'v3' } #1 for key in dic.keys(): print(key) #2 for key in dic.values(): print(key) #3 for key in dic: print(key,dic[key]) #4 dic['k4'] = 'v4' print(dic) #5 dic.pop("k1") print(dic) #6 print (dic.get('k5')) #先获取该值如不为空则可删除 #7 print(dic.get('k2')) #8 print(dic.get('k6')) #9 dic2 = { 'k1':'v111', 'a':'b' } dic2.update(dic) print(dic2) #10 lis =[['k',['qwe',20,{'k1':['tt',3,'1']},89],'ab']] #lis[0][1][2]['k1'][0] = 'TT' #1 #print(lis) lis[0][1][2]['k1'][0] = lis[0][1][2]['k1'][0].upper() #2 print(lis) #11 li = [1,2,3,'a','b','4','c'] dic = {} li_2 = [] for i in range(len(li)): if i %2 ==1: li_2.append(li[i]) run = True while True: user = input("输入查询的值--->") if dic.get(user) == None: dic.setdefault(user,[]) dic[user] = li_2 print(dic) elif dic.get(user) != None: dic[user] = li_2 print(dic)
六、集合
简介:
集合是一个无序的,不重复的数据组合,他的主要作用如下
去重,就是把一个列表变成集合就自动去重了
关系测试,测试两组数据之前的交集,差集,对称差集,并集等关系
l = {1,2,3,4,4,5,2}#创建集合则自动去重 print(l) l.add(7)# add 只能添加不可变数据,并且每次只能添加一个值 print(l) l.pop()#pop 随机删除一个值 print(l) l.remove(3)#remove 删除固定的值,如果值不存在则会报错 print(l) l.discard(6)#discard 删除,如果存在直接删除,如果不存在也不会报错 l.update([1,3,4,5,6,7,89]) #updata 可以增加多个值 print(l) l.clear()# clear 清空集合 print(l) s = [1,2,3,4,5,3,2] print(s) s = set(s)#将字符串转换为集合 print(s)
#输出
{1, 2, 3, 4, 5}
{1, 2, 3, 4, 5, 7}
{2, 3, 4, 5, 7}
{2, 4, 5, 7}
{1, 2, 3, 4, 5, 6, 7, 89}
set()
[1, 2, 3, 4, 5, 3, 2]
{1, 2, 3, 4, 5}
集合中的元素特性:
- 确定性(元素必须可Hash)
- 互异性(去重)
- 无序性(集合中的元素没有先后之分),如集合{3,4,5} 和 {4,5,3}算作同一个集合。
集合关系测试:
交集,在两个集合里都拥有的元素,叫做交集
apple = {'jiu','lin','liang','kun'} banana = {'jiu','lin','zhang','li'} print(apple.intersection(banana)) print(apple & (banana)) #简写 #输出 {'lin', 'jiu'} {'lin', 'jiu'}
差集
在两个集合中,只在其中一个集合的元素
apple = {'jiu','lin','liang','kun'} banana = {'jiu','lin','zhang','li'} print(apple.difference(banana)) #只买了苹果的人 print(apple - (banana)) #简写 print(banana.difference(apple))#只买了香蕉的人 print(banana - (apple)) #输出 {'liang', 'kun'} {'liang', 'kun'} {'li', 'zhang'} {'li', 'zhang'}
并集
将两个集合合并
apple = {'jiu','lin','liang','kun'} banana = {'jiu','lin','zhang','li'} print(apple.union(banana))#将 apple 和banana 合并 print(apple|(banana)) #简写
对称差集
将两个集合中只单独存在一次的元素,合并在一起
apple = {'jiu','lin','liang','kun'} banana = {'jiu','lin','zhang','li'} print(apple.symmetric_difference(banana))#只选择了一种水果的人 print(apple^(banana))#简写 #输出 {'zhang', 'kun', 'liang', 'li'} {'zhang', 'kun', 'liang', 'li'}
包含关系
in,not
in :判断某元素是否在集合内
== , ! =:判断两个集合是否相等
apple = {'jiu','lin','liang','kun'} banana = {'jiu','lin','zhang','li'} print('jiu' in (apple))#判断‘jiu’ 是否在apple里反之 not in
print(apple == banana) #判断两个集合是否相等
#输出
True
False
两个集合之间一般有三种关系,相交、包含、不相交,在python中分别用下面的方法判断:
apple = {'jiu','lin','liang','kun'} banana = {'jiu','lin','zhang','li','liang','kun'} print(apple.isdisjoint(banana))#判断两个集合是否不相交 print(apple.issubset(banana))#判断集合是否被其他集合所包含 print(apple <= (banana))# 简写 print(apple.issuperset(banana))#判断集合是否包含其他合集 print(apple >= banana) #简写 #输出 False True True False False
七、字符编码
二进制, 01
八进制, 01234567
十进制, 0123456789
十六进制, 0123456789ABCDEF
十进制转换8进制和十六进制的语法
万国码 : Unicode ,包含所有语言,可以解释所有编码。
但是unicode中存储英文会多占用一倍空间,所以应景而生 utf-8 ,utf-8 可以根据字符大小,将unicode转换成1-6 个字节, 英文1字节、欧洲2字节、汉字通常是3个字节、其他生僻字占4-6个字节。
1、字符编码转换
python2 默认编码是 ascii ,
字符串编码 默认为 ascii
如果定义为 utf-8 那他的字符编码就是utf-8 ,在代码首行 #encoding:utf-8 (声明编码为utf-8)
python3 默认编码是 utf-8
字符编码为 unicode
编码转换
str = "小九"; str_utf8 = str.encode("UTF-8") #将str编码为指定的bytes类型 str_gbk = str.encode("GBK") print(str) print("UTF-8 编码:", str_utf8) print("GBK 编码:", str_gbk) print("UTF-8 解码:", str_utf8.decode('UTF-8','strict'))#将bytes解码为str 也就是unicode print("GBK 解码:", str_gbk.decode('GBK','strict')) #输出 小九 UTF-8 编码: b'\xe5\xb0\x8f\xe4\xb9\x9d' GBK 编码: b'\xd0\xa1\xbe\xc5' UTF-8 解码: 小九 GBK 解码: 小九
Python 3最重要的新特性之一是对字符串和二进制数据流做了明确的区分。文本总是Unicode
,由str
类型表示,二进制数据则由bytes
类型表示。Python 3不会以任意隐式的方式混用str
和bytes
,你不能拼接字符串和字节流,也无法在字节流里搜索字符串(反之亦然),也不能将字符串传入参数为字节流的函数(反之亦然)。
下面让我们深入分析一下二者的区别和联系。
编码发展的历史
在谈bytes
和str
之前,需要先说说关于编码是如何发展的。。
在计算机历史的早期,美国为代表的英语系国家主导了整个计算机行业,26个英文字母组成了多样的英语单词、语句、文章。因此,最早的字符编码规范是ASCII码,一种8位即1个字节的编码规范,它可以涵盖整个英语系的编码需要。
编码是什么?编码就是把一个字符用一个二进制来表示。我们都知道,所有的东西,不管是英文、中文还是符号等等,最终存储在磁盘上都是01010101这类东西。在计算机内部,读取和存储数据归根结底,处理的都是0和1组成的比特流。问题来了,人类看不懂这些比特流,如何让这些010101对人类变得可读呢?于是出现了字符编码,它是个翻译机,在计算机内部某个地方,透明的帮我们将比特流翻译成人类可以直接理解的文字。对于一般用户,不需要知道这个过程是什么原理,是怎么执行的。但是对于程序员却是个必须搞清楚的问题。
以ASCII
编码为例,它规定1个字节8个比特位代表1个字符的编码,也就是“00000000”这么宽,一个一个字节的解读。例如:01000001表示大写字母A,有时我们会“偷懒"的用65这个十进制来表示A在ASCII
中的编码。8个比特位,可以没有重复的最多表示2的8次方(255)个字符。
后来,计算机得到普及,中文、日文、韩文等等国家的文字需要在计算机内表示,ASCII的255位远远不够,于是标准组织制定出了叫做UNICODE的万国码,它规定任何一个字符(不管哪国的)至少以2个字节表示,可以更多。其中,英文字母就是用2个字节,而汉字是3个字节。这个编码虽然很好,满足了所有人的要求,但是它不兼容ASCII
,同时还占用较多的空间和内存。因为,在计算机世界更多的字符是英文字母,明明可以1个字节就能够表示,非要用2个。
于是UTF-8
编码应运而生,它规定英文字母系列用1个字节表示,汉字用3个字节表示等等。因此,它兼容ASCII
,可以解码早期的文档。UTF-8
很快就得到了广泛的应用。
在编码的发展历程中,我国还创造了自己的编码方式,例如GBK
,GB2312
,BIG5
。他们只局限于在国内使用,不被国外认可。在GBK
编码中,中文汉字占2个字节。
bytes和str之间的异同
回到bytes
和str
的身上。bytes
是一种比特流,它的存在形式是01010001110这种。我们无论是在写代码,还是阅读文章的过程中,肯定不会有人直接阅读这种比特流,它必须有一个编码方式,使得它变成有意义的比特流,而不是一堆晦涩难懂的01组合。因为编码方式的不同,对这个比特流的解读也会不同,对实际使用造成了很大的困扰。下面让我们看看Python是如何处理这一系列编码问题的:
>>> s = "中文" >>> s '中文' >>> type(s) <class 'str'> >>> b = bytes(s, encoding='utf-8') >>> b b'\xe4\xb8\xad\xe6\x96\x87' >>> type(b) <class 'bytes'>
从例子可以看出,s
是个字符串类型。Python有个内置函数bytes()
可以将字符串str
类型转换成bytes
类型,b
实际上是一串01的组合,但为了在ide环境中让我们相对直观的观察,它被表现成了b'\xe4\xb8\xad\xe6\x96\x87'
这种形式,开头的b
表示这是一个bytes
类型。\xe4
是十六进制的表示方式,它占用1个字节的长度,因此”中文“被编码成utf-8
后,我们可以数得出一共用了6个字节,每个汉字占用3个,这印证了上面的论述。在使用内置函数bytes()
的时候,必须明确encoding
的参数,不可省略。
我们都知道,字符串类str
里有一个encode()
方法,它是从字符串向比特流的编码过程。而bytes
类型恰好有个decode()
方法,它是从比特流向字符串解码的过程。除此之外,我们查看Python源码会发现bytes
和str
拥有几乎一模一样的方法列表,最大的区别就是encode
和decode
。
从实质上来说,字符串在磁盘上的保存形式也是01的组合,也需要编码解码。
如果,上面的阐述还不能让你搞清楚两者的区别,那么记住下面两几句话:
-
在将字符串存入磁盘和从磁盘读取字符串的过程中,Python自动地帮你完成了编码和解码的工作,你不需要关心它的过程。
-
使用
bytes
类型,实质上是告诉Python,不需要它帮你自动地完成编码和解码的工作,而是用户自己手动进行,并指定编码格式。 -
Python已经严格区分了
bytes
和str
两种数据类型,你不能在需要bytes
类型参数的时候使用str
参数,反之亦然。这点在读写磁盘文件时容易碰到。
在bytes和str的互相转换过程中,实际就是编码解码的过程,必须显式地指定编码格式。
>>> b
b'\xe4\xb8\xad\xe6\x96\x87' >>> type(b) <class 'bytes'> >>> s1 = str(b) >>> s1 "b'\\xe4\\xb8\\xad\\xe6\\x96\\x87'" >>> type(s1) <class 'str'> >>> s1 = str(b, encoding='utf-8') >>> s1 '中文' >>> type(s1) <class 'str'>
我们再把字符串s1,转换成gbk编码的bytes类型:
>>> s1
'中文' >>> type(s1) <class 'str'> >>> b = bytes(s1, encoding='gbk') >>> b b'\xd6\xd0\xce\xc4'