day02 python的特有结构
列表使用[‘hello’,10]
相当于C中的数组,只是相当于数组,因为数组仅能存储数据类型相同的内容,而python是一种存储数据引用的内容!
lit=['hello','world',98]
他的内容都是存储引用!!!
创建方式:
- 方括号
lit=['sss','asda']
- 使用内置函数lit2=list([‘hello’,‘world’])
特点:
- 列表元素按照顺序有序排序
- **索引映射唯一个数据,0,1,2,3.list[0],list[1]**和数组不一样,它可以逆序索引。lit[0]==lit[-6]
- 列表可以存储重复数据
- 任何数据类型混存
- 根据需要动态分配和回收内存
逆索引 | -6 | -5 | -4 | -3 | -2 | -1 |
---|---|---|---|---|---|---|
数据 | ’hello‘ | ’world‘ | ’you‘ | 99 | ’myself‘ | ’id‘ |
正索引 | 0 | 1 | 2 | 3 | 5 | 6 |
获取单个元素用索引!
list[0]就和list[-6]是一样的!
获取元素的索引index()
**index()方法获取获取列表中指定元素的索引:**获得下标值是多少
使用方法:创建list对象,对象调用index()
lis=['hello','helloo',123,'hello']
print(lis.index('hello'))
print(lis.index('python'))
print(lis.index('hello',1,4))
- 只返回列表中相同元素只返回列表中相同元素的第一个元素的索引
- 查询元素不存在会抛出异常VlaueError
- 指定在start,stop之间检索
获取多个元素用切片
列表名**【start:stop:step】**
结果为原列表的拷贝,范围[start,stop).step默认为1。step为正数时,从start开始切,step为负数时,从stop往前切。!
lst=[10,20,30,40,50,60]
print(lst[1:6:1])#lst[1:6:1]不在是原地址产生一个新的列表
print(lst)
print(lst[4,0,-2])#stop都是不包括的
结果为:
[20, 30, 40, 50, 60]
[10, 20, 30, 40, 50, 60]
[50, 30]
判断元素是否在列表中是否存在
in not in
lis=[10,20,'wer','hello']
print(10 in lst)
print(30 not in lst)
遍历列表中的元素
lis=[10,20,'wer','hello']
for i in lis:
print(i,end=' ')
列表元素的增加操作(类函数)
- append() 列表尾部添加一个元素,标识是否修改?同一个列表
- extend() 列表尾部至少添加一个元素,将两个列表合并,同一个列表
- **insert()**列表的任意位置添加一个元素,插入某个位置,后面元素后移
- 切片 列表任意位置至少添加一个元素,插入切入位置,此后面的元素切除掉
lst=[10,20,30,40]
print('原',id(lst))
lst.append(100)
print('新',id(lst))
print(lst)
"""
原 2224773993088
新 2224773993088
[10, 20, 30, 40, 100]
"""
lst=[10,20,30,40]
print('原',id(lst))
lst2=[40,60,70]
lst.extend(lst2)
print('新',id(lst))
print(lst)
"""
原 1145856725504
新 1145856725504
[10, 20, 30, 40, 40, 60, 70]
"""
lst=[10,20,30,40]
print('原',id(lst))
lst.insert(2,'hello')
print('新',id(lst))
print(lst)
"""
原 2865568092736
新 2865568092736
[10, 20, 'hello', 30, 40]
"""
lis=['hello',10,'world']
lis1=[20.30,'you']
print('原',id(lis))
print(type(id(lis)))
lis[1:]=lis1
print('旧',id(lis))
print(lis)
"""
原 2486004748800
<class 'int'>
旧 2486004748800
['hello', 20.3, 'you']
"""
列表元素的删除操作
- remove() 一次删除一个元素,重复元素只能删除第一个,元素不存在则抛出value Error
- pop() 删除一个指定索引位置的元素,指定索引不存在则抛出Index Error,不指定索引则删除列表最后一个元素。
- 切片 一次至少删除一个元素
- clear() 清空列表
- del 删除列表
lis=[10,20,30,40,30,50,60,70,80,30]
lis.remove(30)
print(lis)
lis.pop(1)
print(lis)
lis.pop()
print(lis)
new_list=lis[1:3]
print(new_list)
lis[1:3]=[]# 不要1-2的元素,用空列表来替换
print(lis)
lis.clear()
print(lis)
del lis
"""
[10, 20, 40, 30, 50, 60, 70, 80, 30]
[10, 40, 30, 50, 60, 70, 80, 30]
[10, 40, 30, 50, 60, 70, 80]
[40, 30]
[10, 50, 60, 70, 80]
"""
列表元素的修改操作
- 为指定索引元素赋予一个新值
lis[2]=100
- 为指定切片赋予一个新值
lis[1:3]=[10,20,30,40]
列表元素的排序操作
- sort()来排序使元素按照从小到大的顺序进行排序,可以指定reverse=Ture,进行降序,排序 对原列表进行操作
- **内置函数sorted(),**可以指定reverse=Ture,进行降序排序,产生一个新的列表
lis=[10,20,30,40,30,50,60,70,80,30]
print(lis,id(lis))
lis.sort()
print(lis,id(lis))
lis.sort(reverse=True)
print(lis)
"""
[10, 20, 30, 40, 30, 50, 60, 70, 80, 30] 1851203719616
[10, 20, 30, 30, 30, 40, 50, 60, 70, 80] 1851203719616
[80, 70, 60, 50, 40, 30, 30, 30, 20, 10]
"""
lis=[10,20,30,40,30,50,60,70,80,30]
print(lis,id(lis))
new_list=sorted(lis)
print(new_list,id(new_list))
new_list=sorted(lis,reverse=True)
print(new_list)
"""
[10, 20, 30, 40, 30, 50, 60, 70, 80, 30] 2579429134912
[10, 20, 30, 30, 30, 40, 50, 60, 70, 80] 2579428077120
[80, 70, 60, 50, 40, 30, 30, 30, 20, 10]
"""
列表生成式
生成列表的公式
[i*i for i in range(1,10)]
i*i表示列表元素的表达式
比如存储1-9的本身数lie=[i for i in range(1,10)]
存储1-9的平方数lie=[i*i for i in range(1,10)]
要求是2,4,6,8,10lie=[i*2 for i in range(1,6)]
字典使用{’hello‘:10}
字典解释
Python内置的数据结构之一,与列表一样是一个可变序列(可以施行增删改)
以键值对的方式存储数据,字典是一个无序的序列,索引不是严格的位置序列,字典的**存储是哈希存储!**哈希存储都是空间换时间的DS
!!!健不允许重复,值允许重复
scores={‘张三’:100,‘李四’:98}
字典名,花括号,健:值,逗号,健(字符串,整数序列)是一个不可变序列
字典的实现原理:Python是根据key查找到value所在的位置
字典的定义
- 使用花括号来创建score={‘张三’:100,‘李四’:90,‘王五’:60}
- 使用内置函数dict() dict(name=‘jack’,age=20)
字典元素值的获取
- 使用[],
scores['张三']
获取张三的值。 若字典中不存在指定的key,抛出keyError异常。 - 类方法:get()方法
scores.get('张三')
get()方法取值不存在指定的key,不会抛异常,而是返回None,可以通过参数设置默认的value。以便指定key不存在时返回!
scores={'张三':100,'what':60}
print(scores['张三'])
print(scores.get('what'))
print(scores.get('hello'))
print(scores.get('hello',50))##默认值
"""
100
60
None
50
"""
字典的操作
- 判断key是否在字典中 in,not in
'张三' in scores
判定条件,返回Ture,Flase - 字典中元素的删除
del scores['张三']
,clear()清空字典内容scores.clear()
- 字典中**元素的新增和修改相同,**有元素则修改,无元素则增加。
scores['jack']=90
视图操作类方法:
- 获取字典中所有的key keys()
- 获取字典中所有value values()
- 获取字典中所有key,value键值对 items()
scores={'张三':100,'李四':90,'王二':50}
keys=scores.keys()
print(keys,type(keys))
valuse=scores.values()
print(valuse)
items=scores.items()
print(items)
"""
dict_keys(['张三', '李四', '王二']) <class 'dict_keys'>
dict_values([100, 90, 50])
dict_items([('张三', 100), ('李四', 90), ('王二', 50)])
[('张三', 100), ('李四', 90), ('王二', 50)]#()元组,列表元素由元组组成
"""
字典元素的遍历
使用for-in来遍历字典,其实获得是健
scores={'张三':100,'李四':90,'王二':50}
for i in scores:
print(i,scores[i])
"""
张三 100
李四 90
王二 50
"""
字典生成式
利用**内置函数zip()**用于将可迭代的对象作为参数,将对象中对应的元素打包成一个元组,然后返回由这些元组组成的列表
items=['Fruits','Books','Others']
prices=[90,80,70]
lst=zip(items,prices)
print(list(lst))
d={item:price for item,price in zip(items,prices)}
print(d)
"""
[('Fruits', 90), ('Books', 80), ('Others', 70)]
{'Fruits': 90, 'Books': 80, 'Others': 70}
"""
字典生成式生成:{item.upper() : price for item,price in zip(item,prices)},upper()是变大写的,两列表元素不相等的话以少的为主。
元组使用(’python‘,10)
元组为内置数据结构,**为不可变序列。**与列表仅相差变化为【】-》()
- 不可变序列:字符串,元组。无增删改操作
- 可变序列:列表,字典。 有增删改,且对象地址不发生更改
为什么要设置成不可变序列
多任务环境下,同时操作对象是不需要加锁,
因此,在程序中尽量使用不可变序列。
注意事项:
元组中存储的是对象的引用,引用不允许在更改!!
-
如果元组中对象本身不可变对象,则不能再引用其他对象。
-
如果元组中的对象是可变对象,则可变对象的引用不允许改变,**但数据可以改变!**但列表的内存地址不变
t=(10,[10,20],10)
元组的创建方式
- 直接用小括号 t=(‘hello’,10,20)也可以写成
t='hello',10,20
- 使用内置函数tuple()
t=tuple(('hello',10))
- 只包含一个元组的元素需要用逗号和小括号
t=('hello',)
逗号不能省
元组的遍历
-
可以通过索引去遍历
-
最好使用for- in来遍历
t=(10,[10,29,30],'hello')
print(t[0])
for i in t:
print(i)
"""
10
10
[10, 29, 30]
hello
"""
集合使用{’hello’,90}
- 内置数据结构
- 与列表和字典一样为可变元组
- 集合没有value!!!只有键key,**且也采用的哈希存储,无法利用索引使用!。**哈希带来的后果也是键值无法重复,仅保留一个
集合的创建
- 直接创建
t={'hello','world'}
- 使用内置函数set()。
s=set({'world','hello'})
###print(set((23,'hello',['nani'],12)))出错TypeError: unhashable type: 'list',可变类型无法建立索引
s={2,2,3,4,5,6,7}
print(s)
t=set(range(6))
print(t,type(t))
print(set([3,2,4,2,6,8]))
print(set((1,2,3,4,4,65)))
print(set('python'))
print(set({'helo',67}))
"""
{2, 3, 4, 5, 6, 7}
{0, 1, 2, 3, 4, 5} <class 'set'>
{2, 3, 4, 6, 8}
{65, 1, 2, 3, 4}
{'o', 't', 'n', 'h', 'y', 'p'}
{'helo', 67}
字典是无序的!!!
"""
定义 空集合如何定义:只能利用set(),.t=set()
集合的相关操作
- 判断元素是否在内 in,not in
- 元素的新增操作 1. add()一次添加一个元素。2. update()至少添加一个元素。
s.add(20),s.update({20,30,40}),s.update([12,3,4]),s.update((23,45))
- 元素的删除操作
- remove()一次删除一个指定元素,若指定不存在则抛出异常
s.remove(100)
- discard() 一次删除一个指定元素,如果不存在不抛出异常
s.discard(20)
- pop() 一次只删除一个任意元素
s.pop()
,无参! - clear() 清空
s.clear()
- remove()一次删除一个指定元素,若指定不存在则抛出异常
集合之间的关系
- 是否相等,只要元素内容相同则就相同和顺序无关,因集合是无序的 ==和!=来判定
- 是否一个是另一个的子集 ,issubset()进行判断,是子集则为Ture
- 是否一个是另一个的超集 , issuperset() 是超集则为Ture
- 两个集合是否有交集 ,isdisjoint() 没有交集则为Ture
s={10,20,30,40,50,60}
s1={10,20,30}
s2={100,200,300}
print(s==s1)
print(s1.issubset(s))
print(s.issuperset(s1))
print(s1.isdisjoint(s))
print(s2.isdisjoint(s))
"""
False
True
True
False
True
"""
集合的数学操作
- 两个集合的交集 使用
s1.intersection(s2)
返回两集合的交集s1&s2
也可以,,,只是产生中间集合,对原集合不改变 - 两个集合的并集 使用
s1.union(s2)
返回两集合的并集 s1|s2也可以。。。。只是产生中间集合,对原集合不改变 - 两个集合的差集 使用
s1.difference(s2)
返回去除相同元素的s1集合元素,和是s1-s2也可以,只是产生中间集合,对原集合不改变 - 两个集合的对称差集,使用
s1.symmetric_difference(s2)
,返回s1,s2中除去共同有的元素的并集,和s1^s2
相同
集合生成式
将列表生成式中的[]改变成{}
{i*i for i in range(1,10)}
生成0-10之间的偶数
s={i*2 for i in range(1,6)}
print(s)
#{2, 4, 6, 8, 10}
特有数据结构的总结
数据结构 | 是否可变 | 是否重复 | 是否有序 | 定义符号 |
---|---|---|---|---|
列表(list) | 可变 | 可重复 | 有序 | [] |
元组(tuple) | 不可变 | 可重复 | 有序 | () |
字典(dict) | 可变 | key不可重复。value可重复 | 无序 | {key:value} |
集合(set) | 可变 | 不可重复 | 无序 | {} |
字符串特殊操作
基本数据类型,是一个不可变的字符序列。
'',"","""""",均可定义
a='hello'
b="hello"
c="""hello"""
print(id(a))
print(id(b))
print(id(c))
d=10
f=10
print(id(10))
print(id(d))
print(id(f))
"""
2593418316016
2593418316016
2593418316016
140719738853312
140719738853312
140719738853312
"""
字符串的驻留机制:
- 仅保存一份相同且不可变字符串的方法,不同的值存放在字符串的驻留池中,Python的驻留机制对相同的字符串只保留一份拷贝,后续创建相同字符串不会开辟新空间,而是把字符串的地址赋给新创建的变量。!!适用于其他任何数据结构
驻留机制的几种情况:
- 字符串长度为0,1
- 字符串内容符合标识符的定义时(只能包含字母数字下划线)
- 字符串只在编译时进行驻留,而非运行时
- [-5,256]之间的整数数字
sys中的intern()方法强制2个字符串指向同一个对象
import sys
a='abc%'
b='abc%'
a=sys.intern(b)
print(a is b)
Pycharm中会强制进行保留机制。
驻留机制的优点:避免频繁的创建预销毁,提高效率和节约内存。因为拼接字符串和修改字符串会比较影响性能的
在使用字符串拼接时,建议使用str类型的join方法,而非+,因为join()方法是先计算所有字符中的长度,然后再拷贝,只new一次对象,效率必+效率高。
字符串的查询操作
- index()
s.index('lo')
查找子串在主串中第一次出现的位置,若字串不存在,则抛出ValueError - rindex()
s.rindex('lo')
查找子串在主串中最后一次出现的位置,如果查找的子串不存在,则抛出ValueError - find()
s.find('lo')
查找子串在主串中第一次出现的位置,如果查找的子串不存在时,则返回-1 - rfind()
s.rfind('lo')
查找的子串在主串中最后一次出现的位置,如果查找的子串不存在,则返回-1
a='hello,hello'
print(a.index('he'))
print(a.rindex('he'))
print(a.find('he'))
print(a.rfind('hee'))
"""
0
6
0
-1
"""
字符串大小写转化
- upper() 字符串所有字符串都转成大写字母
s.upper()
- lower() 字符串所有字符串都转成小写字母
s.lower()
- swapcase() 字符串中大写变小写,小写变大写
s.swapcase
- capitalize() 字符串中的第一个字符变成大写,把其余字符转换为小写
s.capitalize
- title() 将字符串中每个单词的第一个字符转换为大写,把每个单词的剩余字符转换为小写
s.title
使用方式会返回一个中间字符串,源字符串并未改变
a='hello,hello'
print(id(a))
s=a.upper()
print(s,id(s),a,id(a))
"""
2172416755760
HELLO,HELLO 2172416754928 hello,hello 2172416755760
"""
字符串内容对齐操作
- center() 居中对齐,第一个参数指定宽度,第二个参数指定填充字符,第二个参数可选的,默认为空格,设置的宽度小于实际宽度则返回原字符串,
- ljust() 左对齐 第一个参数指定宽度,第二个参数指定填充字符,第二个参数可选的,默认为空格,设置的宽度小于实际宽度则返回原字符串,
- rjust() 右对齐 第一个参数指定宽度,第二个参数指定填充字符,第二个参数可选的,默认为空格,设置的宽度小于实际宽度则返回原字符串,
- zfill() 右对齐 左边用0填充,该方法只接受一个参数,用于指定字符串宽度,设置的宽度小于实际宽度则返回原字符串,
会返回新的字符串
a='hello,Python'
print(a.center(20,'*'))
print(a.ljust(20,'&'))
print(a.rjust(20,'#'))
print(a.rjust(10))##长度不够返回原字符
print(a.zfill(20))
print('-8910'.zfill(8))
"""
****hello,Python****
hello,Python&&&&&&&&
########hello,Python
hello,Python
00000000hello,Python
-0008910
"""
字符串劈分操作
- split() 从字符串的左边开始劈分,默认的劈分字符是空格字符串,返回的值都是以一个列表。 通过参数sep指定劈分字符串的劈分符 通过参数maxsplit指定劈分字符串的最大劈分次数,在经过最大劈分次数之后,剩余的子串会单独作为一部分。
- rsplit() 从字符串的右边开始劈分,默认的劈分字符是空格字符串,返回的值都是以一个列表。通过参数sep指定劈分字符串的劈分符 通过参数maxsplit指定劈分字符串的最大劈分次数,在经过最大劈分次数之后,剩余的子串会单独作为一部分。
s='hello,world'
lst=s.split()
print(lst)
print(s.split(sep=','))
s='hello world python'
lst=s.split()
print(lst)
print(s.split(maxsplit=1))
print(s.rsplit(maxsplit=1))
"""
['hello,world']
['hello', 'world']
['hello', 'world', 'python']
['hello', 'world python']
['hello world', 'python']
"""
字符串判断的方法
- isidentifier() 判断指定字符串是不是合法的标识符
- isspace() 判断指定字符串是否全部由空白字符组成(回车,空格,换行,水平制表符)
- isaloha() 判断指定字符串是否全部由字母组成
- isdecimal() 判断指定字符串是否全部由十进制的数字组成,1,2,3,4,5,6
- isnumeric() 判断指定字符串是否全部由数字组成,包括一,二,三,包括肆,伍,陆,包括罗马数字
- isalnum() 判断指定字符串是否全部由字母和数字组成
s='hello,world'
print('1.',s.isidentifier())
print('2.','hello_123'.isidentifier())
print('3.','\t'.isspace())
print('4.','as_as'.isalpha())
print('5.','123'.isdecimal())
print('6.','123四'.isdecimal())
print('7.','123四肆'.isnumeric())
print('8.','hello123'.isalnum())
"""
1. False
2. True
3. True
4. False
5. True
6. False
7. True
8. True
"""
字符串的替换与合并+
- 字符串的替换 replace() 将主串中的指定子串替换为其他子串的功能!第一个参数指定被替换的子串,第二个参数指定替换的字符串,该方法返回替换后得到的字符串,替换前的字符串不发生变化,本质也是产生新字符串。调用该方法时可以通过第3个参数指定最大替换次数!
- 字符串的合并join() 将列表或元组中的字符串合并成一个字符串
s='hello,python,python,python,python'
print(s.replace('python','world'))
print(s)
print(s.replace('python','world',2))
lst=['hello','world','Python']
print('/'.join(lst))
print(''.join(lst))
t=tuple(('hello','java'))
print('*'.join(t))
print('_'.join('Python'))
"""
hello,world,world,world,world
hello,python,python,python,python
hello,world,world,python,python
hello/world/Python
helloworldPython
hello*java
P_y_t_h_o_n
"""
字符串的比较操作
- 运算符 > ,< , >=, <= , == , !=.==比较的是value的值,is比较的是两个的id是否相等。
- 比较规则:首先比较第一个字符,相等则比较下一个字符,依次比较下去,直到两个字符串中的字符不相等时,其比较结果就是两个字符串的比较结果。两个字符串中的所有后续字符串将不再被比较。
- 比较原理:两个字符进行比较时,比较的是其原始值,调用内置函数ord()就能得到字符的原始值(ASCC码的值a=97,A=65)。同样的知道ASCC码值得到字符利用内置函数chr()
print('apple'>'banana')
print(ord('A'))
print(chr(97))
"""
False
65
a
"""
字符串的切片操作
字符串是不可变类型,不具备增删改操作
切片操作将产生新的对象
**[start:stop:step]**没有开始默认从0可以是正向索引值也可以是负向索引值,没有结束默认到最后一个,默认步长为1.可以为负数,负数则从右往左切
s='hello,world'
s1=s[:5]
s2=s[6:]
print(s1)
print(s2)
print(s[0::2])
"""
hello
world
hlowrd
"""
格式化字符串
有些内容可以改变,有些内容无法改变,就是print中的格式化字符串
- %作占位符
'我的名字%s,%d岁'%(name,age)
右对齐,还有域宽%10d,精度 %.3f小数点后三位, - {}作占位符
hhewifh{0},aahad{1}.format(name,gae)
- f-string,方法
f'姓名:{name},年龄:{age}'
name='张三'
gae=10
print('您的名字:%s,年龄:%d'%(name,gae))
print('你的名字:{0},今年:{1}岁,嘿嘿{0}'.format(name,gae))
print(f'姓名:{name},年龄:{gae}')
"""
您的名字:张三,年龄:10
你的名字:张三,今年:10岁,嘿嘿张三
姓名:张三,年龄:10
"""
print('{0:.3}'.format(3.1415926))#表示一共有三位
print('{0:.3f}'.format(3.1415926))# 表示小数点后三位
print('{0:10.3f}'.format(3.12415926))
"""
3.1415926
3.142
3.124
"""
字符串的编码转换
编码:将字符串转换成二进制数据为(bytes)使用s.encode(encoding='GBK')
解码:将bytes类型的数据转换成字符串类型 s.decode(encoding='GBK')
s='你好世界'
print(s.encode(encoding='GBK'))
print(s.encode(encoding='UTF-8'))
byte=s.encode(encoding='GBK')
print(byte.decode(encoding='GBK'))
"""
b'\xc4\xe3\xba\xc3\xca\xc0\xbd\xe7'
b'\xe4\xbd\xa0\xe5\xa5\xbd\xe4\xb8\x96\xe7\x95\x8c'
你好世界
"""