1.0 列表特点 和创建
”列表中的所有数据都有两个整数类型的索引"
1.1 列表使用的函数
# 列表使用的函数
import random
list=[2,3,4,1,32]
print(len(list)) #5
print(max(list)) #32
print(min(list)) #1
print(sum(list)) # 42
random.shuffle(list) # 随意排列
print(list) # 随机的,如[32, 1, 2, 3, 4]
还有一些功能是序列功能:
python序列
1.2 列表解析
list=[1,2,3,4]
for i in list:
print(i,end=" ") # 1 2 3 4
# 列表解析
print()
list=[x for x in range(5)]
print(list) # [0, 1, 2, 3, 4]
list1=[x for x in range(5) if x>2]
print(list1) # [3, 4]
list2=[x for x in list1 if x<4]
print(list2) # [3]
1.3 列表方法
append(x:object) 添加到结尾
count(x:object) :统计列表中某个元素出现的次数
extend(l:list):列表2追加到列表1中
index(x:object):查找某个元素在列表中首次出现的位置(即索引 > 0,或不存在时抛出ValueError)
index(x, start,stop)
insert(index:int,x:object) 元素x插入指定下标
pop(index):object 没有指定index,就删除list.pop(),返回最后一个元素
使用 del list[i]: 删除列表中元素
remove(x:object):移除列表中某个值的首次匹配项
reverse():None :倒序
sort(reverse=False):对列表中元素进行升序排序(修改自身)
zip():把任何数量的序列“缝合”,按最短序列的长度,返回由元组组成的列表
list.clear():清空
copy(): 复制列表
list=[2,3,4,1,32,4] #创建,也可以 list=list([2,3,4,1,32,4])
list.append(19)
print(list) # [2, 3, 4, 1, 32, 4, 19]
print(list.count(4)) #元素4出现次数 ->2
list2=["hello","world"]
list.extend(list2)
print(list) #[2, 3, 4, 1, 32, 4, 19, 'hello', 'world']
print(list.index(2)) # 0
list.insert(8,"你好世界")
print(list) # [2, 3, 4, 1, 32, 4, 19, 'hello', '你好世界', 'world']
list.pop()
print(list) # [2, 3, 4, 1, 32, 4, 19, 'hello', '你好世界']
del list[len(list)-1]
print(list) # [2, 3, 4, 1, 32, 4, 19, 'hello']
list.remove(2)#元素
print(list) # [3, 4, 1, 32, 4, 19, 'hello']
list.reverse()
print(list)# ['hello', 19, 4, 32, 1, 4, 3]
# list.sort()
# print(list)# 会报错:TypeError: '<' not supported between instances of 'int' and 'str'
# #只能是同类型比较
list=["a","c","A","Z"]
list.sort()
print(list)# ['A', 'Z', 'a', 'c']
list2=list.copy()
print(list2) # ['A', 'Z', 'a', 'c']
lst=[1,2,3]
list(reversed(lst)) # 迭代序列,转换成列表
print(lst) # [1, 2, 3]
lst=[1,2,3]
lst1=["w","b","d",'e']
lst2=list(zip(lst,lst1))
print(lst2)
1.4 字符串分成列表split()
string="I could win"
item=string.split(" ")
print(item)
print(type(item))
1.5 一行输入和多行输入 ,创建列表
s=input("Enter 5 numbers seperated by spaces from one line")
item=s.split()# type(item)=list
lst=[eval(x) for x in item]
print(lst)
lst=[]
print("Enter 5 numbers from several lines")
for i in range(5):
lst.append(eval(input()))
print(lst)
1.6 对列表移位
def leftShift(list):
temp=list[0]
for i in range(len(list)-1):
list[i]=list[i+1]
list[len(list)-1]=temp
list=[3,2,4]
leftShift(list)
print(list)
1.6.1 案例一:判断输入的数字是否涵盖1-99所有数字
isCovered=99*[False]
endOfInput=False
while not endOfInput:
s=input("Enter a line of numbers separated by spaces:")
items=s.split(" ")
lst=[eval(x) for x in items ]
for number in lst:
if number==0:
endOfInput=True
else:
isCovered[number-1]=True
allCovered=True
for i in range(99):
if isCovered[i]==False:
allCovered=False
break
if allCovered:
print("This tickets cover all number from 1->99")
else:
print("The tickets don't cover all numbers")
1.6.2 随机发牌
deck=[x for x in range(52)]
suits=["Spades","Hearts","Diamonds","Club"]
ranks=["Ace","2","3","4","5","6","7","8","9","10","Jack","Queue","King"]
import random
random.shuffle(deck)
for i in range(4):
suit=suits[deck[i]//13] #颜色
rank=ranks[deck[i]%13] # 图案
print("Card number ",deck[i]," is the",rank,"of ",suit)
1.6.3 可视化
# C:\Users\Lenovo\Pictures\Feedback\pukeImage
import random
from tkinter import *
from PIL import ImageTk
class CardGUI:
def __init__(self):
window=Tk()
window.title("Pick your cards randomly")
self.imageList=[]
for i in range(52):
self.imageList.append( ImageTk.PhotoImage(file="C:/Users/Lenovo/Pictures/Feedback/pukeImage/" +str(i+1)+ ".jpg" ) )
frame=Frame(window)
frame.pack()
self.labelList=[]
for i in range(4):
self.labelList.append(Label(frame,image=self.imageList[i]) )
self.labelList[i].pack(side=LEFT)
btShuffle=Button(window,text="Shuffle",command=self.shuffle).pack()
window.mainloop()
def shuffle(self):
random.shuffle(self.labelList)
for i in range(4):
self.labelList[i]["image"]=self.imageList[i]
CardGUI()
扑克牌图案下载
链接: https://pan.baidu.com/s/1Y_63hOT_o25Uo0jhtZ2N4A 提取码: s7y2
1.7 复制
#如果用=直接赋值,是非拷贝方法。这两个列表是等价的,修改其中任何一个列表都会影响到另一个列表。
list0=[1,2,4]
list=list0
print(id(list)==id(list0))
print(list)
#其他的第一层为深复制,其他层为浅复制
#其他的深复制
# 对于list的第一层,是实现了深拷贝,但对于嵌套的list,仍然是浅拷贝。
# 内层的list保存的是地址,复制过去的时候是把地址复制过去了。嵌套的list在内存中指向的还是同一个。
# 深拷贝主要是将另一个对象的属性值拷贝过来之后,另一个对象的属性值并不受到影响,
# 因为此时它自己在堆中开辟了自己的内存区域,不受外界干扰。
# 浅拷贝主要拷贝的是对象的引用值,当改变对象的值,另一个对象的值也会发生变化。
# 使用列表生成式1
list1=[x for x in list]
print(id(list1)==id(list))# False
list1=list1+[list]
list1[3][1]=10
print(list)
print(list1)
# 使用列表生成式2
list2=[]+list
print(id(list2)==id(list))# False
list2=list2+[list]
list2[3][1]=100
print(list)
print(list2)
# copy()方法
list3=list.copy()
print(id(list3)==id(list))# False
list3=list3+[list]
list3[3][1]=1000
print(list)
print(list3)
# 深拷贝
# 如果用deepcopy()方法,
# 则无论多少层,无论怎样的形式,得到的新列表都是和原来无关的,使用时,要导入copy。
import copy
old = [1,[1,2,3],3]
new = copy.deepcopy(old)
print('Before:')
print(old)
print(new)
new[0] = 3
new[1][0] = 3
print('After:')
print(old)
print(new)
1.8 返回列表
def m(x,lst=[1,1,2,3]):
if x in lst:
lst.remove(x)
return lst
def main():
list1=m(1)
print(list1)
list2=m(1)
print(list2)
main()
def m(x,lst=None):
if lst!=None:
if x in lst:
lst.remove(x)
return lst
def main():
list1=m(1)
print(list1)
list2=m(1,[2,3,1])
print(list2)
main()
1.9 排序
1.9.0 内置排序
1.9.1 选择排序
#选择排序
import random
def selectSort(list):
for i in range(len(list)):
currentMin=list[i]
currentMinIndex=i
for j in range(i+1,len(list)):
if currentMin>list[j]:
currentMin=list[j]
currentMinIndex=j
if currentMinIndex!=i:
list[currentMinIndex]=list[i]
list[i]=currentMin
return list
def main():
list=[x for x in range(12) ]
random.shuffle(list)
print(list)
selectSort(list)
print(list)
main()
1.9.2 插入排序
#选择排序
import random
def insertSort(list):
for i in range(1,len(list)):
#和前面排好的比较
currentElement=list[i]
k=i-1
while k>=0 and list[k]>currentElement:
list[k+1]=list[k]
k-=1
list[k+1]=currentElement
def main():
list=[x for x in range(12) ]
random.shuffle(list)
print(list)
insertSort(list)
print(list)
main()
1.9.3快速排序
# 快速排序
import random
def Partition(list, low, high):
privotkey = list[low]
while low < high:
while low < high and list[high] >= privotkey:
high -= 1
list[low] = list[high]
while low < high and list[low] <= privotkey:
low += 1
list[high] = list[low]
list[low]= privotkey
return low
def quickSort(list, low, high):
if low < high:
pivotloc = Partition(list, low, high)
quickSort(list, low, pivotloc - 1)
quickSort(list, pivotloc + 1, high)
def main():
list = [x for x in range(12)]
random.shuffle(list)
print(list)
low = 0
high = len(list)-1
quickSort(list, low, high)
print(list)
main()
1.9.4 用队列实现的弹球动画
from tkinter import *
from random import randint
class Ball:
def __init__(self):
self.radius = 3
self.x = self.radius
self.y = self.radius
self.dx = 2
self.dy = 2
self.color = self.getRandomColor()
def getRandomColor(self):
color = "#"
for j in range(6):
color += self.toHexChar(randint(0, 15))
return color
def toHexChar(self, hexValue):
if 0 <= hexValue <= 9:
return chr(hexValue + ord("0"))
else:
return chr(hexValue + ord("A") - 10)
class BounceBall:
def stop(self):
self.isStop = True
def resume(self):
self.isStop = False
self.animate()
def Add(self):
self.ballList.append(Ball())
def remove(self):
self.ballList.pop()
def faster(self):
if self.sleepTime > 10:
self.sleepTime -= 10
def slower(self):
self.sleepTime += 10
def exit(self):
self.isStop = True
self.window.quit() # 会停下再关闭
#self.window.destroy() #在动画运行立即退出,会报错
# “quit()会停止TCL解释器.这在大多数情况下都是你想要的,因为你的Tkinter-app也会停止.如果你从空闲中调用你的应用程序,这可能是一个问题
# .buturn本身就是一个Tkinker-app,因此,如果您在应用程序中调用quit()并且TCL解释器被终止,则空闲也将终止(或混淆).
# destroy()只是终止mainloop并删除所有小部件.因此,如果您从另一个Tkinter应用程序调用您的应用程序,或者如果您有多个主循环,那么它似乎更安全.“
def __init__(self):
self.ballList = [Ball()]
self.window = Tk()
self.window.title("Bouncing balls")
self.width = 350
self.height = 150
self.canvas = Canvas(self.window, width=self.width, height=self.height, bg="white")
self.canvas.pack()
frame = Frame(self.window).pack()
btStop = Button(self.window, text="STOP", command=self.stop).pack(side=LEFT)
btResume = Button(self.window, text="RESUME", command=self.resume).pack(side=LEFT)
btAdd = Button(self.window, text="+", command=self.Add).pack(side=LEFT)
btRemove = Button(self.window, text="-", command=self.remove).pack(side=LEFT)
btFaster = Button(self.window, text="Faster", command=self.faster).pack(side=LEFT)
btSlower = Button(self.window, text="Slower", command=self.slower).pack(side=LEFT)
btExit = Button(self.window, text="Exit-doubleClick", command=self.exit).pack(side=LEFT)
self.sleepTime = 100
self.isStop = False
self.animate()
self.window.mainloop()
def animate(self):
while not self.isStop:
self.canvas.after(self.sleepTime)
self.canvas.update()
self.canvas.delete("ball")
for i in self.ballList:
self.redisplayBall(i)
def redisplayBall(self, ball):
if (ball.x + ball.radius) > self.width or (ball.x - ball.radius) < 0:
ball.dx = -ball.dx
if (ball.y + ball.radius) > self.height or (ball.y - ball.radius) < 0:
ball.dy = -ball.dy
ball.x += ball.dx
ball.y += ball.dy
self.canvas.create_oval(ball.x - ball.radius, ball.y - ball.radius,
ball.x + ball.radius, ball.y + ball.radius,
fill=ball.color, tags="ball")
BounceBall()
1.9.5改进的全屏的弹珠游戏
from tkinter import *
from random import randint
class Ball:
def __init__(self):
self.radius =randint(60, 100)
self.x = self.radius
self.y = self.radius
self.dx = 2
self.dy = 2
self.color = self.getRandomColor()
def getRandomColor(self):
color = "#"
for j in range(6):
color += self.toHexChar(randint(0, 15))
return color
def toHexChar(self, hexValue):
if 0 <= hexValue <= 9:
return chr(hexValue + ord("0"))
else:
return chr(hexValue + ord("A") - 10)
class BounceBall:
def stop(self):
self.isStop = True
def resume(self):
self.isStop = False
self.animate()
def Add(self):
self.ballList.append(Ball())
def remove(self):
self.ballList.pop()
def faster(self):
if self.sleepTime > 10:
self.sleepTime -= 10
def slower(self):
self.sleepTime += 10
def exit(self):
self.isStop = True
self.window.quit() # 会停下再关闭
#self.window.destroy() #在动画运行立即退出,会报错
# “quit()会停止TCL解释器.这在大多数情况下都是你想要的,因为你的Tkinter-app也会停止.如果你从空闲中调用你的应用程序,这可能是一个问题
# .buturn本身就是一个Tkinker-app,因此,如果您在应用程序中调用quit()并且TCL解释器被终止,则空闲也将终止(或混淆).
# destroy()只是终止mainloop并删除所有小部件.因此,如果您从另一个Tkinter应用程序调用您的应用程序,或者如果您有多个主循环,那么它似乎更安全.“
def __init__(self):
self.ballList = [Ball()]
self.window = Tk()
self.window.title("Bouncing balls")
# 获取屏幕宽、高尺寸
root_w, root_h = self.window.winfo_screenwidth(), self.window.winfo_screenheight()
# 取消边框
self.window.overrideredirect(1)
self.width =root_w
self.height = root_h-30
self.canvas = Canvas(self.window, width=self.width, height=self.height, bg="white")
self.canvas.pack()
frame = Frame(self.window).pack()
btStop = Button(self.window, text="STOP", command=self.stop).pack(side=LEFT)
btResume = Button(self.window, text="RESUME", command=self.resume).pack(side=LEFT)
btAdd = Button(self.window, text="+", command=self.Add).pack(side=LEFT)
btRemove = Button(self.window, text="-", command=self.remove).pack(side=LEFT)
btFaster = Button(self.window, text="Faster", command=self.faster).pack(side=LEFT)
btSlower = Button(self.window, text="Slower", command=self.slower).pack(side=LEFT)
btExit = Button(self.window, text="Exit-doubleClick", command=self.exit).pack(side=LEFT)
self.sleepTime = 100
self.isStop = False
self.animate()
self.window.mainloop()
def animate(self):
while not self.isStop:
self.canvas.after(self.sleepTime)
self.canvas.update()
self.canvas.delete("ball")
for i in self.ballList:
self.redisplayBall(i)
def redisplayBall(self, ball):
if (ball.x + ball.radius) > self.width or (ball.x - ball.radius) < 0:
ball.dx = -ball.dx
if (ball.y + ball.radius) > self.height or (ball.y - ball.radius) < 0:
ball.dy = -ball.dy
ball.x += ball.dx
ball.y += ball.dy
self.canvas.create_oval(ball.x - ball.radius, ball.y - ball.radius,
ball.x + ball.radius, ball.y + ball.radius,
fill=ball.color, tags="ball")
BounceBall()
主要是增加了以下代码,实现了全屏
self.window = Tk()
self.window.title("Bouncing balls")
# 获取屏幕宽、高尺寸
root_w, root_h = self.window.winfo_screenwidth(), self.window.winfo_screenheight()
# 取消边框
self.window.overrideredirect(1)
self.width =root_w
self.height = root_h-30
self.canvas = Canvas(self.window, width=self.width, height=self.height, bg="white")
self.canvas.pack()
1.9.6 按钮事件+列表实现的改进版
这个代码转自https://blog.csdn.net/weixin_42402407/article/details/84992004
import random
import tkinter
import tkinter.messagebox
class RandomBall():
'''
单个球定义、运动的类
'''
def __init__(self, root_canvas, width, height):
'''
参数说明:
canvas:从ScreenSaver类中传入的画布
width,height:从SS类中传入的宽高,即屏幕宽高
'''
# 将传入变量赋为RB类的属性
self.canvas = root_canvas
self.width = width
self.height = height
# 随机生成球的中心坐标
self.xcenter = random.randint(100, width-100)
self.ycenter = random.randint(100, height-100)
# 随机生成球的运动速度
self.xvelocity = random.randint(8,16)
self.yvelocity = random.randint(8,16)
# 计算球的半径
self.radius = random.randint(60, 100)
# 利用十六进制随机数与lambda表达式生成球的颜色
# RGB表示法:三个数字,每个数字的值是0-255之间,表示红绿蓝三个颜色的大小
# 在某些系统中,直接用英文单词表示也可以,比如red,green
color = lambda : random.randint(0,255)
self.color = '#%02x%02x%02x' % (color(),color(),color())
# 创建球的函数
def create_ball(self):
'''
用构造函数定义的变量值,在canvas上画一个球
'''
# tkinter没有画圆形函数
# 只有一个画椭圆函数,画椭圆需要定义两个坐标,
# 在一个长方形内画椭圆,我们只需要定义长方形左上角和右下角就好
# 求两个坐标的方法是,已知圆心的坐标,则圆心坐标减去半径能求出
# 左上角坐标,加上半径能求出右下角坐标(向右x为正,向下y为正)
xleftup = self.xcenter - self.radius
yleftup = self.ycenter - self.radius
xrightdown = self.xcenter + self.radius
yrightdown = self.ycenter + self.radius
# 创建球
self.item = self.canvas.create_oval(xleftup,yleftup,
xrightdown,yrightdown,
fill=self.color,
outline=self.color)
# 球运动的函数
def move_ball(self):
# 计算球移动后的中心点坐标
self.xcenter += self.xvelocity
self.ycenter += self.yvelocity
# 当球与边框发生碰撞时,需要进行回弹操作,即对应方向的速度取负
if self.xcenter + self.radius >= self.width:
self.xvelocity = - self.xvelocity
if self.xcenter - self.radius <= 0:
self.xvelocity = - self.xvelocity
if self.ycenter + self.radius >= self.height:
self.yvelocity = - self.yvelocity
if self.ycenter - self.radius <= 0:
self.yvelocity = - self.yvelocity
# 在canvas上移动球,前提是create_ball已经调用
self.canvas.move(self.item, self.xvelocity, self.yvelocity)
class ScreenSaver():
'''
屏保定义类
程序启动
'''
def __init__(self):
# 创建球存储列表
self.balls = []
# 随机生成球的数量
self.num = random.randint(10,20)
# 利用tkinter生成root窗口
self.root = tkinter.Tk()
# 获取屏幕宽、高尺寸
root_w, root_h = self.root.winfo_screenwidth(), self.root.winfo_screenheight()
# 取消边框
self.root.overrideredirect(1)
# 绑定退出函数与相应动作
self.root.bind('<Motion>', self.myquit)
self.root.bind('<Key>', self.myquit)
self.root.bind('<Any-Button>', self.myquit)
# 创建画布,配置尺寸与颜色属性
self.canvas = tkinter.Canvas(self.root, width=root_w, height=root_h)
self.canvas.pack()
# 利用循环与RandomBall类在画布上画球,并append到列表中
for i in range(self.num):
ball = RandomBall(self.canvas, width=root_w, height=root_h)
ball.create_ball()
self.balls.append(ball)
# 调用球运动函数
self.run_screen_saver()
# 启用tkinter时间消息循环mainloop
self.root.mainloop()
# 球运动函数
def run_screen_saver(self):
# 循环实例化的ball调用move_ball函数
for ball in self.balls:
ball.move_ball()
# 使用after实现递归,通过不断调用各球的move_ball函数,实现位置刷新
self.root.after(50, self.run_screen_saver)
# 停止运行
# 此处e只是利用了事件处理机制,际上并不关心事件的类型
def myquit(self, e):
# 扩展:
# 此屏保程序扩展成,一旦捕获事件,则判断屏保不退出
# 显示一个Button,Button上显示事件类型,点击Button后屏保才退出
if tkinter.messagebox.askokcancel("彩球碰撞", '确定退出?'):
self.root.destroy()
else:
pass
if __name__ == '__main__':
# 启动屏保
ScreenSaver()
1.10 列表切片
切片的语法格式:[start:stop:step],其中,
1. 得到的切片仍然是列表,是原始列表的片段的一份拷贝。
2.得到的切片不包括索引stop对应的元素。
3.如果不指定step,其默认值是1,此时语法格式可以简化为[start:stop]。
4.当step为正数时,
如果不指定start,切片的第一个元素默认是列表的第一个元素。
如果不指定stop,切片的最后一个元素默认是列表的最后一个元素。
从索引start开始往后计算切片。
当step为负数时,
如果不指定start,切片的第一个元素默认是列表的最后一个元素。
如果不指定stop,切片的最后一个元素默认是列表的第一个元素。
从索引start:开始往前计算切片。
5.切片操作是允许索引越界的
6.可以调用内置函数slice(类s1ice的构造方法)创建slice类型的对象
内置函数slice有三种调用方式:
1.slice(stop)
2.slice(start,stop)
3.slice(start,stop,step)
start、stop和step的默认值都是None。
slice(start,stop,step)与start:stop:step是等价的。
# 给切片赋值
name=list("Perl")
name[1:]=list("ython")
print(name) # ['P', 'y', 't', 'h', 'o', 'n']
# 不动原来数值,增加数据
name[1:1]=list("@")
print(name) # ['P', '@', 'y', 't', 'h', 'o', 'n']
# 删除切片
name[1:6]=[]
print(name) # ['P', 'n']
1.11 列表插入 (4种)
1.12 列表删除(5种)
1.13 列表的加法运算
1.14 列表的乘法运算
1.15 列表的比较
1.16 列表反转(3种)
如果想对列表中的所有元素进行反转,常见的方式有两种:
1、 调用方法reverse (修改自身)
2、调用内置函数reversed
内置函数reversed的返回值是一个迭代器对象,且被反转的列表不发生变化