内置数据结构(变量类型)
- list
- set (详见 python-数据类型)
- dict (详见 python-数据类型)
- tuple
list(列表)
- 一组有顺序的数字的组合
- 创建列表
- 空列表
l1=[] #创建一个空列表
print(type(l1))
print(l1)
l2=[100] #创建一个带值得列表
print(type(l2))
print(l2)
l3=[2,5,5,8,1,3] #创建带多个值得列表
print(type(l3))
print(l3)
l4=list() #创建一个空列表
print(type(l4))
print(l4)
运行结果:
<class 'list'>
[]
<class 'list'>
[100]
<class 'list'>
[2, 5, 5, 8, 1, 3]
<class 'list'>
[]
Process finished with exit code 0
列表常用操作1
- 访问
- 使用下标操作(索引)
- 列表的位置是从0开始的(规定列表最后一个下标为 -1)
- 分片操作
- 对列表进行任意一段的截取
- list [ : ] (截取范围是从冒号前到冒号后,但是冒号后的数字取不到)
(冒号前后可以为空,前为空表示从位置0开始,后为空表示截止最大数加一,即截取到最后一个数据) - list [ : : ] (第二个冒号表示增长幅度,默认增长幅度为1,即一个一个增长,如果此数为负值,则表示顺序为从右往左)
#下标访问列表
l=[2,3,5,4,1,6]
print(l)
print(l[4]) #提取下标数字
print(l[2:4]) #提取从下标二到下标三
print(l[ :5]) #提取从第一个到下标四
print(l[2:]) #提取从下标二到最后一个
print(l[ : :2]) #从第一个到最后一个间隔为2
print(l[-2:-5]) #下面显示为空是因为分片默认顺序是从左往右,正常情况下冒号左边的数要小于右边的数
print(l[-5:-2])
print(l[-2:-5:-1]) #如果非要这么写,则需要吧步长写为负数,但是截取的结果也是颠倒的
运行结果:
[2, 3, 5, 4, 1, 6]
1 #提取下标数字
[5, 4] #提取从下标二到下标三
[2, 3, 5, 4, 1] #提取从第一个到下标四
[5, 4, 1, 6] #提取从下标二到最后一个
[2, 5, 1] #从第一个到最后一个间隔为2
[]
[3, 5, 4]
[1, 4, 5]
Process finished with exit code 0
分片操作是生成一个新的list
- 内置函数id,负责显示一个变量或者数据的唯一确定编号
l=[2,5,3,8,4,6]
ll=l[:]
l[1]=100
#l 和 ll 不是同一个列表
print(id(l))
print(id(ll))
print(l)
print(ll)
运行结果:
287737405960
287737406024
[2, 100, 3, 8, 4, 6]
[2, 5, 3, 8, 4, 6]
Process finished with exit code 0
list(列表)操作2
- del 删除命令
- del一个变量后,此变量将无法在使用
#del案例
l=[2,5,3,8,4,6]
print(id(l))
del l[2]
print(id(l))
print(l)
运行结果:
770037604872
770037604872 #运行del函数后不会形成一个新的list,仍然是原来那个
[2, 5, 8, 4, 6]
Process finished with exit code 0
- 列表相加
- 使用加号连接两个列表
#列表相加案例
a=[1,2,3,4]
b=[5,6,8]
c=['a', 'b', 'c']
d=a+b+c
print(d)
运行结果:
[1, 2, 3, 4, 5, 6, 8, 'a', 'b', 'c']
Process finished with exit code 0
- 列表数乘
- 列表直接跟整数相乘,相当于把n个列表连在一起
#列表数乘案例
a=[1,2,3,4]
b=a*3
print(b)
运行结果:
[1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]
Process finished with exit code 0
- 成员资格运算
- 就是判断一个元素是否在list中
a=[1,2,3,4]
b=3
c=b in a
print(c)
运行结果:
True
- 列表的遍历
- for
- while (一般不用while访问列表)
#列表遍历案例:
a=[1,2,3,4]
for i in a:
print(i)
b=['i love sunyue']
for i in b:
print(i)
print("#"*20)
#以下是while用法
l=len(a)
n=0 #n表示列表的下标
while n<l:
print(a[n])
n += 1
运行结果:
1
2
3
4
i love sunyue
####################
1
2
3
4
Process finished with exit code 0
- 双层列表循环
#a为嵌套列表,又称双层列表
a=[["one",1],["two",2],["three",3]]
for k,v in a:
print(k,"---",v)
运行结果:
one --- 1
two --- 2
three --- 3
Process finished with exit code 0
列表内涵:list content
- 通过简单方法创建列表
#用for创建
a=[x for x in range(1,6 )]
b=[i for i in a] #对于a中得每一个元素,逐个放入到b中
print(b)
c=[i*10 for i in a] #将a中得每一个元素乘10 ,再逐个放入到c中
print(c)
d=[m for m in a if m % 2 ==0] #过滤:将a中得偶数提取出来放到d中
print(d)
f=[m+n for m in a for n in b] #相当于两个for循环嵌套,且同样可以使用条件表达式
print(f)
运行结果:
[1, 2, 3, 4, 5]
[10, 20, 30, 40, 50]
[2, 4]
[2, 3, 4, 5, 6, 3, 4, 5, 6, 7, 4, 5, 6, 7, 8, 5, 6, 7, 8, 9, 6, 7, 8, 9, 10]
Process finished with exit code 0
- 一些题外话
#传值和传址的区别
#对于简单的数值,采用传值操作,即在函数内对参数的操作不影响外面的变量
#对于复杂变量,采用的是传地址操作,此时函数内的和外面的数据是同一份,不管在哪里更改都会影响其内容
def a(n):
n[2]=300
print (n)
return None
def b(n):
n += 100
print (n)
return None
an=[1,2,3,4,5,6,7]
bn=9
print(an)
a(an) #传址,会对其中的数值进行修改
print(an)
print(bn)
b(bn) #传值,只会改变传过来的数据,但不会改变原始数据
print (bn)
运行结果:
[1, 2, 3, 4, 5, 6, 7]
[1, 2, 300, 4, 5, 6, 7]
[1, 2, 300, 4, 5, 6, 7]
9
109
9
关于列表的函数
len(): 表示列表的长度
cmp(list1,list2):比较两个列表的元素
max(): 表示列表中的最大值(同理还有min)
list():将其他形式的数据转换为list(前提是可以转换)
zip():将序列中的元素按照顺序进行配对组成一个元组,然后将这些元组放到新的序列当中。
- zip()函数返回的是zip类型,需要用list()函数进行转换
names = ['吴承恩', '罗贯中', '施耐庵', '曹雪芹']
books = ['西游记', '三国演义', '水浒传', '红楼梦']
times = ['1501年-1582年', '1330年—1400年', '1296年—1370年', '1715年-1763年']
books_info = zip(names, books, times)
print(list(books_info))
# 输出:[('吴承恩', '西游记', '1501年-1582年'), ('罗贯中', '三国演义', '1330年—1400年'), ('施耐庵', '水浒传', '1296年—1370年'), ('曹雪芹', '红楼梦', '1715年-1763年')]
append(): 表示插入一个内容,在末尾追加
sort():将列表元素排序
index(x):返回第一次出现x元素的索引值
a = [i for i in range(1,5)]
print(a)
a.append(100)
print(a)
运行结果:
[1,2,3,4]
[1,2,3,4,100]
insert(): 表示指定位置插入
括号中需要定义两个值,一个表示位置下标,一个表示插入值
insert(index,data)插入的值是index的前面
a = [i for i in range(1,5)]
print(a)
a.insert(2,50)
print(a)
运行结果:
[1, 2, 3, 4]
[1, 2, 50, 3, 4]
del 删除:它是根据索引(元素所在位置)来删除
str=[1,2,3,4,5,2,6]
del str[1] #删除下标为1的元素
print(str)
[1, 3, 4, 5, 2, 6]
str=[0,1,2,3,4,5,6]
del str[2:4] #删除从第2个元素开始,到第4个为止的元素(但是不包括尾部元素)
print(str)
[0, 1, 4, 5, 6]
pop():从队尾拿出一个元素,即吧最后一个元素取出来,括号里也可以输入指定下标
remove(x):在列表中删除第一次出现的元素x
clear():清空
#列表的删除实例
a = [i for i in range(1,10)]
print(a)
print(id(a))
#pop删除实例
last_del=a.pop() #通常pop用于赋值
print("提取出来的值为:",last_del)
print(a)
print(id(a)) #id一样,说明是同一个列表
b = a.pop(6)
print("提取出来下标为6的值为:",b)
print(a)
print(id(a))
#remove删除实例
a.remove(2) #删除a中数值为2的元素
print(a)
print(id(a)) #id一样,说明是同一个列表
#clear清空实例
a.clear() #清空一个列表
print(a)
print(id(a)) #id一样,说明是同一个列表
运行结果:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
722993177096
提取出来的值为: 9
[1, 2, 3, 4, 5, 6, 7, 8]
722993177096
提取出来下标为6的值为: 7
[1, 2, 3, 4, 5, 6, 8]
722993177096
[1, 3, 4, 5, 6, 8]
722993177096
[]
722993177096
reverse 翻转列表内容
#列表的翻转实例
a = [i for i in range (1,10)]
print(a)
print(id(a))
a.reverse()
print(a)
print(id(a)) #id一样,说明是同一个列表
运行结果:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
292435288584
[9, 8, 7, 6, 5, 4, 3, 2, 1]
292435288584
extend 扩展列表,将两个列表中的一个直接拼接到另一个的后面
#列表的扩展实例
a = [i for i in range (1,10)]
b = [i for i in range (10,15)]
print(a)
print(id(a))
a.extend(b)
print(a)
print(id(a))
运行结果:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
62002192904
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
62002192904
count 查找列表中指定值或者元素的个数
#列表的count实例
a = [1,2,5,3,5,4,5,1,2,1]
print(a)
print(id(a))
n= int(input("请输入数字:")) #input输入的是字符,需要转换为int类型
b = a.count(n)
print("列表中{}的个数为:".format(n),b)
运行结果:
[1, 2, 5, 3, 5, 4, 5, 1, 2, 1]
637753188872
请输入数字:5
列表中5的个数为: 3
copy 拷贝, 浅拷贝
a = [1,2,3,4,5]
print(a)
b = a #list类型,简单赋值操作,是传地址
b[3] = 77
print("更改b的值后a的值为:",a)
print("a的ID地址为:",id(a))
print("更改b的值后b的值为:",b)
print("b的ID地址为:",id(b))
print("*"*20)
#拷贝实例
b = a.copy()
print("a的值为:",a)
print("a的ID地址为:",id(a))
print("b的值为:",b)
print("b的ID地址为:",id(b)) #copy之后ID地址发生改变
print("*"*20)
b[3] = 88
print("更改b的值后a的值为:",a)
print("更改b的值后b的值为:",b)
运行结果:
[1, 2, 3, 4, 5]
更改b的值后a的值为: [1, 2, 3, 77, 5]
a的ID地址为: 33841672
更改b的值后b的值为: [1, 2, 3, 77, 5]
b的ID地址为: 33841672
********************
a的值为: [1, 2, 3, 77, 5]
a的ID地址为: 33841672
b的值为: [1, 2, 3, 77, 5]
b的ID地址为: 34328264
********************
更改b的值后a的值为: [1, 2, 3, 77, 5]
更改b的值后b的值为: [1, 2, 3, 88, 5]
- 深拷贝和浅拷贝的区别
- 深拷贝需要特定的工具
a0 = [10,20,30]
a = [1,2,3,a0]
b = a.copy()
print(id(a[3]))
print(id(b[3])) #拷贝以后b中a0的地址没有发生变化
a[3][2] = 666
#浅拷贝,只拷贝一层内容
#也就是说,b拷贝的是a,而b中的a0还是指向原地址,所以改变b中a0的值后,a中a0的值也发生改变
print(a)
print(b)
运行结果:
4809224
4809224
[1, 2, 3, [10, 20, 666]]
[1, 2, 3, [10, 20, 666]]
元组-tuple
- 元组可以看成是一个不可更改的list
- tuple写在一个小括号里,元素之间用逗号隔开。
- 元组的元素不可变,但是可以包含可变对象,如list。
- 元组可以用作字典的键,也可以作为集合的元素,但是列表就不可以,包含列表的元组也不可以。
元组创建
#创建空元组
t = ()
print(type(t))
<class 'tuple'>
#创建一个只有一个值的元组
t = (1,)
print(type(t))
print(t)
<class 'tuple'>
(1,)
t = 1,
print(type(t))
print(t)
<class 'tuple'>
(1,)
# 创建多个值得元组
t = 1,2,3,4,5
print(type(t))
print(t)
<class 'tuple'>
(1, 2, 3, 4, 5)
#使用其他结构创建
l = [1,2,3,4]
t = tuple(l)
print(type(t))
print(t)
<class 'tuple'>
(1, 2, 3, 4)
元组的特性
- 是序列表,有序
- 元组数据值可以访问,不能修改
- 元组数据可以是任意类型
- 总之,list所有特性,除了可修改,元组都具有。 也就意味着,list具有的一些操作,比如索引,分片,序列相加,相乘,成员资格操作等都一模一样
生成器表达式
gen = (2**i for i in range(8)) #创建一个生成器对象
#生成器使用一次后就用完了,之后再次使用就是空的
print(gen)
print((gen)) #转换为列表
print(tuple(gen))
gen = (2**i for i in range(8))
print(next(gen)) #使用next()函数访问下一个元素
print(next(gen))
for item in gen: #使用for循环访问剩下的所有元素
print(item,end = ' ')
gen的输出结果为: <generator object <genexpr> at 0x000001D43FF88E48>
list(gen)的输出结果为: [1, 2, 4, 8, 16, 32, 64, 128]
tuple(gen)的输出结果为: ()
第一次结果为: 1
第二次结果为: 2
剩余所有结果为:
4 8 16 32 64 128