04常用的数据结构探究
常用的数据结构探究
一、字符串
字符串的定义方式
#字符串的表示
s1 = 'hello, world!'
s2 = "hello, world!"
# 以三个双引号或单引号开头的字符串可以折行
s3 = """
hello,
world!
"""
print(s1, s2, s3, end='')
#转义字符,两个\\就是再转义
#\n代表换行
varstr='我叫黄圳峰\n他叫即顺利'
print(varstr)
'''我叫黄圳峰
他叫即顺利'''
#\r作为光标起点,忽略前面
varstr='我叫黄圳峰\r他叫即顺利'
print(varstr)
'''他叫即顺利'''
#\t制表符=四个空格
varstr='我叫黄圳峰\t他叫即顺利'
print(varstr)
'''我叫黄圳峰 他叫即顺利'''
#\b退格
varstr='我叫黄圳峰\b他叫即顺利'
print(varstr)
'''我叫黄圳他叫即顺利'''
#在字符串前面加r
varstr=r'我叫黄圳峰\b他叫即顺利'
print(varstr)
'''我叫黄圳峰\b他叫即顺利'''
字符串相关操作
s1 = 'hello ' * 3
print(s1) # hello hello hello
s2 = 'world'
s1 += s2
print(s1) # hello hello hello world
print('ll' in s1) # True
print('good' in s1) # False
str2 = 'abc123456'
# 从字符串中取出指定位置的字符(下标运算)
print(str2[2]) # c
# 字符串切片(从指定的开始索引到指定的结束索引)
print(str2[2:5]) # c12
print(str2[2:]) # c123456
print(str2[2::2]) # c246
print(str2[::2]) # ac246
print(str2[::-1]) # 654321cba,回文
print(str2[-3:-1]) # 45
字符串的格式方法
#format()格式化字符串
#1 普通方式
a='李白'
b='!'
vars='{}床前明月光,疑是地上霜{}'.format(a,b)
print(vars)
#2 索引传参
vars1='{0}床前明月光,疑是地上霜{1}'.format('a','b')
print(vars1)
#3 关键字传参
vars2='{a}床前明月光,疑是地上霜{b}'.format(a='libai',b='wo')
print(vars2)
#4 容器数据类型传参
var3='{0[1]},{0[2]},{1[0]}'.format(['a','b','c'],[1])
print(var3)
data={'a':'huang','b':'li'}
var4='{a}和{b}'.format(**data)
print(var4)
#5 限定小数的位数
var5='圆周率是:{:.2f}'.format(3.1415)
print(var5)
print('这是%d'%a)
#f方法
a='e'
var6=f'abcd{a}'
print(var6)
字符串的处理
#大小写处理
#字符串的处理
str1 = 'hello, world!'
# 通过内置函数len计算字符串的长度
print(len(str1)) # 13
# 获得字符串首字母大写的拷贝
print(str1.capitalize()) # Hello, world!
# 获得字符串每个单词首字母大写的拷贝
print(str1.title()) # Hello, World!
# 获得字符串变大写后的拷贝
print(str1.upper()) # HELLO, WORLD!
#大小写互换
print(str1.swapcase())
#字符串的检测
#都是大写?
print(str1.isupper())#False
#都是小写?
print(str1.islower())#True
#首字母打写?
print(str1.istitle())#False
# 检查字符串是否以指定的字符串开头
print(str1.startswith('He')) # False
print(str1.startswith('hel')) # True
# 检查字符串是否以指定的字符串结尾
print(str1.endswith('!')) # True
# 将字符串以指定的宽度居中并在两侧填充指定的字符
print(str1.center(50, '*'))
# 将字符串以指定的宽度靠右放置左侧填充指定的字符
print(str1.rjust(50, ' '))
str2 = 'abc123456'
# 检查字符串是否由数字构成
print(str2.isdigit()) # False
# 检查字符串是否以字母构成
print(str2.isalpha()) # False
# 检查字符串是否以数字和字母构成
print(str2.isalnum()) # True
str3 = ' jackfrued@126.com '
print(str3)
#字符串查找
# 从字符串中查找子串所在位置,返回第一个位置
print(str1.find('or')) # 8
print(str1.find('shit')) # 未找到返回-1
print(str1.rfind('or'))#从右往左开始找,返回第一个位置
# 与find类似但找不到子串时会引发异常
print(str1.index('or'))# 8
print(str1.index('shit'))#引发异常
print(str1.rindex('shit'))#引发异常
#统计字符在字符串中出现的次数
print(str1.count('o'))
#字符串操作
#split:拆分字符串
str1 = 'hello, world!world'
ls1=str1.split(',')
print(ls1)#['hello', ' world!world']
#join:合并字符串
str1 = 'hello, world!world'
ls1=str1.split('o')
print(ls1)#['hell', ', w', 'rld!w', 'rld']
ls2='@'.join(ls1)
print(ls2)#hell@, w@rld!w@rld
#rsplit vs split
str1 = 'hello, world!world'
ls1=str1.split('o',2)
print(ls1)#['hell', ', w', 'rld!world']
ls2=str1.rsplit('o',2)
print(ls2)#['hello, w', 'rld!w', 'rld']
# 获得字符串修剪左右两侧空格或者其他字符之后的拷贝
print(str3.strip())
print(str3.lstrip())
print(str3.rstrip())
#replace替换字符
str1 = 'hello, world!world'
print(str1.replace('hello','hi'))
二、列表
列表的定义和基本操作
#列表的切片
fruits2 = fruits[1:4]
print(fruits2) # apple strawberry waxberry
# 可以通过完整切片操作来复制列表
fruits3 = fruits[:]
print(fruits3) # ['grape', 'apple', 'strawberry', 'waxberry', 'pitaya', 'pear', 'mango']
fruits4 = fruits[-3:-1]
print(fruits4) # ['pitaya', 'pear']
# 可以通过反向切片操作来获得倒转后的列表的拷贝
fruits5 = fruits[::-1]
print(fruits5) # ['mango', 'pear', 'pitaya', 'waxberry', 'strawberry', 'apple', 'grape']
#列表的遍历
# 通过循环用下标遍历列表元素
for index in range(len(list1)):
print(list1[index])
# 通过for循环遍历列表元素
for elem in list1:
print(elem)
# 通过enumerate函数处理列表之后再遍历可以同时获得元素索引和值
for index, elem in enumerate(list1):
print(index, elem)
列表相关函数
#列表的操作
list1 = [1, 3, 5, 7, 100]
# 添加元素
list1.append(200)#append是最后加上
list1.insert(1, 400)#insert是在1的位置加上400
#合并列表
list1.extend([1000, 2000])
list1 += [1000, 2000]
# 先通过成员运算判断元素是否在列表中,如果存在就删除该元素
if 3 in list1:
list1.remove(3)
# 从指定的位置删除元素
list1.pop(0)
# 清空列表元素
list1.clear()
#index返回第一个的位置
list1.index(1)
#列表的排序
list1 = ['orange', 'apple', 'zoo', 'internationalization', 'blueberry']
list2 = sorted(list1)
# sorted函数返回列表排序后的拷贝不会修改传入的列表
# 函数的设计就应该像sorted函数一样尽可能不产生副作用
list3 = sorted(list1, reverse=True)
# 通过key关键字参数指定根据字符串长度进行排序而不是默认的字母表顺序
list4 = sorted(list1, key=len)
#浅拷贝和深拷贝
#浅拷贝
ls1=[1,2,3,4]
ls2=ls1.copy()
print(id(ls1),id(ls2))#140551113116744 140551113134600
ls3=[[1,2,3],[4,5,6]]
ls4=ls3.copy()
print(id(ls3),id(ls4))#140383668153224 140383668153288
print(id(ls3[0]),id(ls4[0]))#140383668153160 140383668153160
# 深拷贝:不仅拷贝外层,还要拷贝内层
import copy
ls5=[[1,2,3],[4,5,6]]
ls6=copy.deepcopy(ls5)
print(id(ls5[0]),id(ls6[0]))#140687075716104 140687075734600
列表推导式
# 定义一个列表[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# 方式1
varlist1=[]
for i in range(10):
varlist1.append(i**2)
print(varlist1)
#方式2
varlist2=list(map(lambda x:x**2,range(10)))
print(varlist2)
#方式3 列表推倒式
varlist3=[x**2 for x in range(10)]
print(varlist3)
# ls1='1234'==>[2,4,6,8]
ls1='1234'
varlist4=[2*int(x) for x in ls1]
print(varlist4)
#带有判断条件的列表推导式
varlist5=[x for x in range(10) if x%2==0]
print(varlist5)
varlist6=[(x,y) for x in range(10) for y in range(10) if x!=y]
print(varlist6)
列表推倒式练习
# exp1
dic1={'user':'admin','age':20,'phone':'123'}
ls1=[f'{key}={value}'for key,value in dic1.items()]
print(ls1)#['user=admin', 'age=20', 'phone=123']
# exp2
ls2=['AAAAA','bbBbb','CCccc']
ls2_=[x.lower() for x in ls2]
print(ls2_)#['aaaaa', 'bbbbb', 'ccccc']
#exp3
ls3=[(x,y) for x in range(6) for y in range(6) if x%2==0 if y%2!=0]
print(ls3)#[(0, 1), (0, 3), (0, 5), (2, 1), (2, 3), (2, 5), (4, 1), (4, 3), (4, 5)]
# exp4
ls4=[f'{i}*{j}={i*j}'for i in range(10) for j in range(10)]
print(ls4)#['0*0=0', '0*1=0', '0*2=0', '0*3=0', '0*4=0', '0*5=0', '0*6=0', '0*7=0', '0*8=0', '0*9=0', '1*0=0', '1*1=1', '1*2=2', '1*3=3', '1*4=4', '1*5=5', '1*6=6', '1*7=7', '1*8=8', '1*9=9', '2*0=0', '2*1=2', '2*2=4', '2*3=6', '2*4=8', '2*5=10', '2*6=12', '2*7=14', '2*8=16', '2*9=18', '3*0=0', '3*1=3', '3*2=6', '3*3=9', '3*4=12', '3*5=15', '3*6=18', '3*7=21', '3*8=24', '3*9=27', '4*0=0', '4*1=4', '4*2=8', '4*3=12', '4*4=16', '4*5=20', '4*6=24', '4*7=28', '4*8=32', '4*9=36', '5*0=0', '5*1=5', '5*2=10', '5*3=15', '5*4=20', '5*5=25', '5*6=30', '5*7=35', '5*8=40', '5*9=45', '6*0=0', '6*1=6', '6*2=12', '6*3=18', '6*4=24', '6*5=30', '6*6=36', '6*7=42', '6*8=48', '6*9=54', '7*0=0', '7*1=7', '7*2=14', '7*3=21', '7*4=28', '7*5=35', '7*6=42', '7*7=49', '7*8=56', '7*9=63', '8*0=0', '8*1=8', '8*2=16', '8*3=24', '8*4=32', '8*5=40', '8*6=48', '8*7=56', '8*8=64', '8*9=72', '9*0=0', '9*1=9', '9*2=18', '9*3=27', '9*4=36', '9*5=45', '9*6=54', '9*7=63', '9*8=72', '9*9=81']
#exp5
M=[
[1,2,3],
[4,5,6],
[7,8,9]
]
N=[
[2,2,2],
[3,3,3],
[4,4,4]
]
lsj=[]
lsy=[]
for i in M:
for j in i:
lsj.append(j)
for x in N:
for y in x:
lsy.append(y)
MN=[[M[i][j]*N[i][j] for j in range(3)] for i in range(3)]
print(MN)#[[2, 4, 6], [12, 15, 18], [28, 32, 36]]
MN_=[M[i][j]*N[i][j] for i in range(3) for j in range(3)]
print(MN_)#[2, 4, 6, 12, 15, 18, 28, 32, 36]
三、元组
占用空间小,不可修改,元组虽然不能改变,但是可以进行切片操作和运算操作。
元组推导式 生成器
#元组推导式是一个生成器,生成器是一种特殊的迭代器
#使用元组推倒式构建生成器
newt=(i**2 for i in range(10))
print(newt)# at 0x7ff7b02c04c0>
#获取生成器数据
# 1、使用next()
# 2、使用list()、tuple
# 3、for
#使用yield,yield可以暂停,返回值之后可以继续
def hello():
print('1')
yield 1
print('2')
yield 2
res=hello()
print(res)#
# print(next(res))#1 1
# print(list(res))#2 [2]
#用生成器改写Feb
def Feb():
yield 1
yield 1
num1=1
num2=1
while True:
num3=num1+num2
num1,num2=num2,num3
yield num3
res=Feb()
for i in range(100):
print(res.__next__())
四、集合
集合的定义和基本操作
'''定义集合'''
#定义一个集合
varset={1,2,3,4,5}
#定义一个集合
varset=set('123456')#{'4', '1', '6', '5', '2', '3'}
#定义空集合
varset=set()#set()
#直接定义会变成字典
varset={}#{}
print(varset,type(varset))
#判断元素是否在集合中
print(1 in varset)#True
#计算长度
print(len(varset))#5
#清空集合
varset.clear()
print(varset)#set()
'''集合的增加一个元素或者多个元素'''
# 添加元素,如果要添加一个对象,我们最好使用add
varset.add(6)
print(varset)#{1, 2, 3, 4, 5, 6}
#如果要把列表或者元组更新到集合当中,最好使用update,注意update中必须是可迭代对象,一个数字就不可以
varlist=['a',1,4]
vartuple=(22,45)
varset.update(varlist,vartuple)
print(varset)#{1, 2, 3, 4, 5, 6, 45, 'a', 22}
'''删除元素'''
#discard,删除一个元素,即使没有也不会报错
varset.discard(3)
varset.discard(6)
print(varset)#{1, 2, 4, 5}
#remove,如果没有这个元素会报错
varset.remove(3)
print(varset)#{1, 2, 4, 5}
#pop,弹出左边第一个元素并可以接收
varset={2,4,5,23}
x1=varset.pop()
x2=varset.pop()
x3=varset.pop()
x4=varset.pop()
print(x1,x2,x3,x4)#2 4 5 23
冰冻集合
#frozenset定义冰冻集合,一经定义不能修改
集合运算
'''集合运算'''
varset1={1,2,3,4}
varset2={3,4,5,6}
print(varset1&varset2)#{3, 4}
print(varset1|varset2)#{1, 2, 3, 4, 5, 6}
print(varset1-varset2)#{1, 2}
print(varset1^varset2)#{1, 2, 5, 6}不同时在1或2中的元素
五、字典
基本操作
# 创建字典
scores = {'骆昊': 95, '白元芳': 78, '狄仁杰': 82}
item1=dict(one=1,two=2,three=3,four=4)
item2=dict(zip(['a','b','c'],'123'))#[('a', '1'), ('b', '2'), ('c', '3')]
item3=dict(([1,2],[2,4]))#{1: 2, 2: 4},类似item2
item4={num:num**2 for num in range(1,10)}
#输出字典
for key in scores:
print(f'{key}:{scores[key]}')
for key,value in enumerate(scores):
print(f'{key}:{value}')
#字典的更新
scores['白元芳'] = 65
scores['诸葛王朗'] = 71
scores.update(冷面=67, 方启鹤=85)
#删除项目
del scores['']
相关函数
#字典转为迭代器之后里面是所有的keys
dict1=dict(a=1,b=2,c=3)
print(dict1)#{'a': 1, 'b': 2, 'c': 3}
print(list(iter(dict1)))#['a', 'b', 'c']
#弹出,后进先出
scores.popitem()
#弹出项目,返回value,可以设定默认值
print(scores.pop('w',100))
#get方法用来取值,没有的可以设定返回值
print(dict1.get('d','没有'))#没有
#update更新字典
dict1.update(d=4,e=5)
dict1.update({'a':10})
print(dict1)#{'a': 10, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
#setdefault检查是否存在,存在则返回值,不存在则插入,同时返回值
print(dict1.setdefault('d', '123'))#123
print(dict1)#{'a': 1, 'b': 2, 'c': 3, 'd': '123'}
字典推倒式
#字典推导式
dict1={'a': 1, 'b': 2, 'c': 3}
dict2={v:k for k,v in dict1.items()}
print(dict2)#{1: 'a', 2: 'b', 3: 'c'}
容器数据类型的转换
'''容器数据类型转换'''
#字符串转列表、集合、元组、字典,把字符串拆开了
varstr='abcde'
print(list(varstr))
print(set(varstr))
print(tuple(varstr))
# ['a', 'b', 'c', 'd', 'e']
# {'c', 'b', 'd', 'e', 'a'}
# ('a', 'b', 'c', 'd', 'e')
print(dict(varstr))#转不了字典
# 列表转集字符串、集合、元组、字典
varlist=[1,2,3,5,6]
print(str(varlist))
print(set(varlist))
print(tuple(varlist))
print(dict(varlist))#转不了字典
# [1, 2, 3, 5, 6]没什么变化
# {1, 2, 3, 5, 6}
# (1, 2, 3, 5, 6)
# 字典转集字符串、集合、元组、列表,只有键没有值
vardict={'huang':1,'ying':2}
print(str(vardict))
print(set(vardict))
print(tuple(vardict))
print(list(vardict))
# {'huang': 1, 'ying': 2}
# {'ying', 'huang'}
# ('huang', 'ying')
# ['huang', 'ying']
# 元组转集字符串、集合、字典、列表,除了字典都可以转
var=(1,2,3,4)
print(str(var))
print(set(var))
# print(dict(var))
print(list(var))
# (1, 2, 3, 4)
# {1, 2, 3, 4}
# [1, 2, 3, 4]
# 集合转集字符串、元组、字典、列表,除了字典都可以转
var={1,2,3,4,5}
print(str(var))
print(tuple(var))
# print(dict(var))
print(list(var))
# {1, 2, 3, 4, 5}
# (1, 2, 3, 4, 5)
# [1, 2, 3, 4, 5]
#2级容器,且每一个里面只有两个值的时候是可以转换为字典的,集合里面只有元组可以的
n=[[1,2],[2,3]]
n=((1,2),(2,3))
n={(1,2),(2,3)}
# n=([1,2,3],[2,3,4])#ValueError: dictionary update sequence element #0 has length 3; 2 is required
n={[1,2],[2,3]}
print(dict(n))
脚本小练习
-
在屏幕上跑马灯文字
import time import os sentenc1='北京欢迎你' while True: os.system('cls') print(sentenc1) time.sleep(0.2) sentenc1=sentenc1[1:]+sentenc1[0]
-
设计一个函数返回给定文件名的后缀
import time import os sentenc1='北京欢迎你' while True: os.system('cls') print(sentenc1) time.sleep(0.2) sentenc1=sentenc1[1:]+sentenc1[0]
-
随机产生验证码的函数
import random def yanzhengma(num): ''' :param num:验证码长度 :return: 验证码 ''' letter_num='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' #['','','',''] list1=random.sample(letter_num,num) str1='' for i in list1: str1+=i return str1 print(yanzhengma(10))
-
设计一个函数返回传入的列表中最大和第二大的元素的值
def max_min(list1): list2=sorted(list1,reverse=True) return list2[0],list2[1] print(max_min([2,3,5,7,1,8,9]))
-
设计函数计算指定日期是这年的多少天
def days(year,month,day): month_day=0 months=[31,28,31,30,31,30,31,31,30,31,30,31] if (year%4==0 or year%400==0) and year%100!=0: months[1]=29 for i in range(month): month_day+=months[i] days=month_day+day return print(days) days(1996,6,26)
-
打印杨辉三角
#制造空列表的方法是[None]*3,就会得到[None,None,None] #同理[[]]*3,得到[[],[],[]] def yanghui_tri(num): ''' :param num:杨辉三角的层数 :return: 杨辉三角 ''' list1=[[]]*num for i in range(num): list1[i]=[None]*(i+1) for j in range(i+1): if j == 0 or j== i: list1[i][j]=1 else: list1[i][j]=list1[i-1][j-1]+list1[i-1][j] print(list1[i][j],end='\t') print() if __name__ == '__main__': yanghui_tri(8)
-
双色球选号
from random import sample,randint def random_select(): ''' 双色球选号 :return:[a,b] ''' red_balls=[x for x in range(1,34)] selected_balls=sample(red_balls,6) selected_balls.sort() selected_balls.append(randint(1,16)) return selected_balls def show_balls(selected_balls): for i in range(len(selected_balls)): if i == len(selected_balls)-1: print('|',end='') print(selected_balls[i],end=' ') if __name__ == '__main__': for i in range(10): show_balls(random_select()) print()
-
约瑟夫环问题
""" 《幸运的基督徒》 有15个基督徒和15个非基督徒在海上遇险,为了能让一部分人活下来不得不将其中15个人扔到海里面去,有个人想了个办法就是大家围成一个圈,由某个人开始从1报数,报到9的人就扔到海里面,他后面的人接着从1开始报数,报到9的人继续扔到海里面,直到扔掉15个人。由于上帝的保佑,15个基督徒都幸免于难,问这些人最开始是怎么站的,哪些位置是基督徒哪些位置是非基督徒。 """ duilie=[True]*30 # print(duilie) #计数 count=0 dead_man=0 while dead_man<15: for index,person in enumerate(duilie): if person: count+=1 if count==9: duilie[index]=False dead_man += 1 count=0 for i in range(len(duilie)): if duilie[i]: duilie[i]='基督徒' else: duilie[i]='普通人' print(duilie)
-
井字棋游戏
from random import sample def print_board(board): print(board['TL'] + '|' + board['TM'] + '|' + board['TR']) print('-+-+-') print(board['ML'] + '|' + board['MM'] + '|' + board['MR']) print('-+-+-') print(board['BL'] + '|' + board['BM'] + '|' + board['BR']) def main(): list1=[] counter=0 init_board={'TL':' ','TM':' ','TR':' ', 'ML':' ','MM':' ','MR':' ', 'BL':' ','BM':' ','BR':' '} print_board(init_board) current_board = init_board.copy() while counter<9: person=input('请你落子:') current_board[person]='*' counter+=1 print_board(current_board) #电脑下 for key,value in current_board.items(): if value ==' ': list1.append(key) computer=sample(list1,1) current_board[computer[0]]='o' counter+=1 print_board(current_board) list1.clear() if __name__ == '__main__': main()
-
华氏度转换为摄氏度
#输入华氏度 F=float(input('请输入华氏温度:')) #转化成摄氏度 C=(F-32)/1.8 #打印 print('%.2f华氏度=%.2f摄氏度'%(F,C))
-
输入圆的半径计算周长和面积
#输入圆的半径 r=float(input('请输入圆的半径:')) #计算周长和面积 d=2*3.14*r s=2*3.14*r**2 #打印出来 print('半径为%.2f的圆的周长为%.2f,面积为%.2f'%(r,d,s))年份是不是闰年
-
判断年份是不是闰年
def is_run(year): if year%4==0 or year%400==0: if year%100!=0: return True return False #输入年份 while True: year=int(input('请输入年份:')) if is_run(year): print('这是一个闰年') else: print('这是一个平年')