数据类型详解-元组
元组和列表一样都是一组有序的数据的组合。
元组中的元素一但定义不可以修改,因此元组称为【不可变数据类型】
1.元组定义
-
定义空元组 a = (),或者 a=tuple()
-
还可以使用 a = (1,2,3) 定义含有数据的元组
-
【注意:如果元组中只有一个元素时,必须加逗号 a=(1,)】
如果不加,a就是int类型
a = (1) print(a,type(a)) >>>1 <class 'int'> a = (1,) print(a,type(a)) >>>(1,) <class 'tuple'>
-
特例:a=1,2,3 这种方式也可以定义为一个元组
2.元组的相关操作
由于元组是不可变的数据类型,因次只能使用索引进行访问,不能进行其它操作;
元组可以和列表一样使用切片方式获取元素;
元组的切片操作 和列表是一样的。
- 切片
【注意!如果步进值为负,则开始值和结束值要反过来写!】
【如果没有反过来,还是索引值从小到大,则输出为空】
a = 1,2,3,4,5,6
print(a[5:0:-1])
>>>(6, 5, 4, 3, 2)
- len(tuple)
- tuple.count():统计一个元素在元组中出现的次数
- tuple.index():获取一个元素在元素中第一次出现的索引值
- tuple + 操作:合并元组
- tuple * 操作
3.元组推导式:返回的是生成器
列表推导式结果返回了一个列表,元组推导式返回的是生成器
生成器是一个特殊的迭代器
列表推导式 ==> [变量运算 for i in 容器] ==> 结果 是一个 列表
元组推导式 ==> (变量运算 for i in 容器) ==> 结果 是一个 生成器
生成器的定义:【就是迭代器的一种】
生成器是一个特殊的迭代器,生成器可以自定义,也可以使用元组推导式去定义;
生成器是按照某种算法去推算下一个数据或结果,只需要往内存中存储一个生成器,节约内存消耗,提升性能。
语法:
-
里面是推导式,外面是一个() 的结果就是一个生成器;【就是由元组推导式得到的】
-
自定义生成器,含有yield关键字的函数就是生成器
含有yield关键字的函数,返回的结果是一个迭代器,换句话说,生成器函数就是一个返回迭代器的函数
如何操作生成器:和操作迭代器一样
a = [1,2,3,4,5]
x = [i *2 for i in a] #返回列表
y = (i *2 for i in a) #返回生成器
print(type(x))
print(type(y))
>>><class 'list'>
<class 'generator'>
#使用next函数去调用
print(next(y))
#使用list或者tuple函数
print(list(y)) #是列表
>>>[1,2,3,4,5]
print(tuple(y)) #是元组
>>>(1,2,3,4,5)
#使用for遍历
for i in y:
yield关键字:
yield关键字使用在 生成器函数中:
- yield 和函数中的 return 有点像
- 共同点:执行到这个关键字后会把结果返回
- 不同点:
- return 会把结果返回,并结束当前函数的调用
- yield 会返回结果,并记住当前代码执行的位置,下一次调用时会从上一次离开的位置继续向下执行
【list()和tuple()函数去调用生成器返回的迭代器时,会把迭代器的返回结果作为容器的元素】
#定义一个普通函数
def func():
print('11')
return 1 # return在函数中会把结果返回,并且结束当前的函数,后面的代码不再执行
print('22')
return 2
print(func())
>>>11
1
def func():
print('11')
yield 1
print('22')
yield 2
print(func()) #返回的是个生成器
>>><generator object func at 0x000001BFEEB54CC8>
print(tuple(func())) #使用生成器返回的迭代器
>>>11
22
(1,2) #如果是list(func())打印的就是[1,2]
#因为返回的是个生成器,所以要用调用生成器的方法获得元素
def func():
yield 1
yield 2
a = func()
print(next(a)) #使用生成器返回的迭代器
print(next(a))
>>>1
2
【注意!!这里如果没有参数a,直接print(func()),那么不管print几次输出都只有1,因为每次都从函数头开始调用】
生成器函数调用时的过程:
首先调用生成器函数,返回一个迭代器
- 第一次调用迭代器:
走到当前的生成器函数中,遇到了 yield 1,把1返回,并且记住来当前的执行状态(位置),暂停了执行,等待下一次的调用;
- 第二层调用迭代器:
从上一次遇到的yield位置开始执行,遇到了 yield 2 ,把2返回,并记住状态,暂停执行,等待下一次调用;
- 第三次去调用迭代器:
从上一次遇到的yield位置开始执行,遇到 yield 3 , 把3返回,并记住了状态,暂停执行,等待下一次调用;
如果在最后又调用了迭代器,那么会从上一次的 yield位置开始,结果后面没有了,直接就超出范围,报错。
使用yield实现斐波那契数列【多复习这道题】:
def func(n):
n0, n1 = 0,1
count = 0
while n > count:
yield n1
n2 = n0 + n1
n0,n1 = n1,n2
count += 1
a = int(input("请输入正整数n:"))
n = func(a)
print(list(n))
'''
这里还可以写成:
a = int(input("请输入正整数n:"))
for i in func(a):
print(i,end = ' ')
'''
#还可以用while True实现
def func():
n0, n1 = 0,1
while True:
yield n1
n2 = n0 + n1
n0,n1 = n1,n2
a = int(input("请输入正整数n:"))
n = func()
for i in range(a):
print(next(n),end=',')