和列表相似,本质上是一种有序的集合元组和列表的不同之处:
a. 列表:[ ] 元组: ()b. 列表中的元素可以进行增加和删除操作,但是,元组中的元素不能修改【元素:一旦被初始化,将不能发生改变】
创建元组
创建列表:
创建空列表: list1=[]创建有元素的列表: list1=[ 元素 1 ,元素 2 ,。。。。。 ]
创建元组:
创建空元组:tuple1=()
创建有元素的元组:tuple1=(元素1,元素2,。。。。)
#1.创建空元组
tuple1=()
print(type(tuple1)) #<class'tuple'>
#2.创建带有元素的元组
tuple2=(12,34,6,87)
print(tuple2)
print(type(tuple2)) #<class'tuple'>
#3.元组中的元素可以是各种类型
tuple3=(12,34,4.12,"lala",True,m)print(tuple3)
#注意:创建的元组只有一个元素时,会在元素的后面加上一个逗号,
tuple4=(2)
print(tuple4)
print(type(tuple4)) #<class'int'>
tuple5=(3,)
print(tuple5)
print(type(tuple5)) #<class'tuple'>
元组元素的访问
tuple1=(14,32,35,7,87)
#1.访问元组的元素,使用下标访问,下标默认从0开始
print(tuple1[1])
print(tuple1[5]) # tuple index out of range索引越界
print(tuple1[-1]) #87 访问元组的最后一个元素下标是-1
print(tuple1[-3]) #35
#2.元组的元素的值不能进行修改
tuple1[2]=99
print(tuple1)#'tuple' object does not support item assignment
#3.删除元组del
del tuple1
print(tuple1) # name 'tuple1' is not defined
元组操作
一个元组中如果有两个元素,我们就称之为二元组;
一个元组中如果五个元素,我们就称之为五元组。
需要提醒大家注意:
( )表示空元组,但是如果元组中只有一个元素,需要加上一个逗号,否则( )就不是代表元组的字面量语法,而是改变运算优先级的圆括号,所以('hello', )和(100, )才是一元组,而('hello')和(100)只是字符串和整数。
# 空元组
a = ()
print(type(a)) # <class 'tuple'>
# 不是元组
b = ('hello')
print(type(b)) # <class 'str'>
c = (100)
print(type(c)) # <class 'int'>
# 一元组
d = ('hello', )
print(type(d)) # <class 'tuple'>
e = (100, )
print(type(e)) # <class 'tuple'>
# 1.定义一个三元组
t1 = (30, 10, 55)
# 定义一个四元组
t2 = ('喜羊羊', 40, True, '青青草原')
# 2.查看变量的类型
print(type(t1), type(t2)) # <class 'tuple'> <class 'tuple'>
# 查看元组中元素的数量
print(len(t1), len(t2)) # 3 4
# 3.通过索引运算获取元组中的元素
print(t1[0], t1[-3]) # 30 30
print(t2[3], t2[-1]) # 青青草原 青青草原
# 4.合并元组,拼接 +
tuple1=(12,34,56)
tuple2=(3.12,56,"hello")
print(tuple1+tuple2)
t3 = t1 + t2
print(t3) # (30, 10, 55, '喜羊羊', 40, True, '青青草原')
# 5.重复元组中的元素 *
tuple3=(23,45,67)
print(tuple3*4)
# 6.判断指定元素是否在元组中使用成员运算符 in和not in
print(56 in tuple2)
if"hello"in tuple2:
print("终于找到你")
else:
print("你在哪里呢!")
print(100 in t1) # False
print(40 in t2) # True
# 7.元组的截取(切片)
tuple4=(12,3,5,7,98)
print(tuple4[1:4]) #(3,5,7)
print(tuple4[-1:]) #(98,)
print(tuple4[:2]) #(12,3)
# 8.比较运算
t1 = (30, 10, 55)
print(t1 == t3) # False
print(t1 >= t3) # False
print(t1 < (30, 11, 55)) # True
元组功能
#元组常见的功能
#1.len获取元组的长度
print(len(tuple4)) #5
#2.获取元组中的最大值max()和最小值min()
print(max(tuple4)) #98
print(min(tuple4)) #3
#3.其他数据类型转换为元组tuple()
list1=[12,34,57,89]
print(type(list1)) #<class'list'>
print(type(tuple(list1))) #<class'tuple'>
#4.遍历元组
#第一种方式:for in
for i in tuple4:
print(i)
#第二种方式:通过下标访问
for i in range(len(tuple4)):
print(tuple4[i])
#第三种方式:enumrate()返回索引和元素
for key,value in enumerate(tuple4):
print(key,value)
二维元组
#二维元组
tuple2=(12,34,5,6,(763,341,23),980,89)
print(tuple2)
print(tuple2[3]) #6
print(tuple2[4][1]) #二维元组的访问
赋值
#赋值:其实就是对象的引用(别名)
list=[12,34,57,9]
list1=list
list[1]=78
#print(list,list1)
浅拷贝
#浅拷贝:拷贝父对象,不会拷贝对象内部的子对象.浅拷贝一维列表的时候,前后两个列表是独立的.
import copy
a = [12, 35, 98, 23] # 一维列表
b = a.copy()
a[1] = 67
print(f'a的值为{a}, b的值为{b}')
# a的值为[12, 67, 98, 23], b的值为[12, 35, 98, 23]
#浅拷贝在拷贝二维列表的时候,只能拷贝最外层列表,不能拷贝父对象中的子对象,当修改子对象中的值的时候,新拷贝的对象也会发生变化
c = [14, 53, 25, [31, 89, 26], 42] # 二维列表
d = c.copy()
c[3][1] = 11
print(f'c的值为{c}, d的值为{d}')
# c的值为[14, 53, 25, [31, 11, 26], 42], d的值为[14, 53, 25, [31, 11, 26], 42]
深拷贝
#若要解决浅拷贝处理二维列表时的问题,需要使用深拷贝解决
import copy
e = [14, 53, 25, [31, 89, 26], 42] # 二维列表
f = copy.deepcopy(e)
e[3][1] = 11
print(f'e的值为{e}, f的值为{f}')
# e的值为[14, 53, 25, [31, 11, 26], 42], f的值为[14, 53, 25, [31, 89, 26], 42]
元组的应用场景
# 打包
a = 1, 10, 100
print(type(a), a) # <class 'tuple'> (1, 10, 100)
# 解包
i, j, k = a
print(i, j, k) # 1 10 100
在解包时,如果解包出来的元素个数和变量个数不对应,会引发ValueError异常,错误信息为:too many values to unpack(解包的值太多)或not enough values to unpack(解包的值不足)。
a = 1, 10, 100, 1000
i, j, k = a # ValueError: too many values to unpack (expected 3)
i, j, k, l, m, n = a # ValueError: not enough values to unpack (expected 6, got 4)
有一种解决变量个数少于元素的个数方法,就是使用星号表达式。有了星号表达式,我们就可以让一个变量接收多个值,需要注意的是,用星号表达式修饰的变量会变成一个列表,列表中有0个或多个元素。还有在解包语法中,星号表达式只能出现一次。

a = 1, 10, 100, 1000
i, j, *k = a
print(i, j, k) # 1 10 [100, 1000]
i, *j, k = a
print(i, j, k) # 1 [10, 100] 1000
*i, j, k = a
print(i, j, k) # [1, 10] 100 1000
*i, j = a
print(i, j) # [1, 10, 100] 1000
i, *j = a
print(i, j) # 1 [10, 100, 1000]
i, j, k, *l = a
print(i, j, k, l) # 1 10 100 [1000]
i, j, k, l, *m = a
print(i, j, k, l, m) # 1 10 100 1000 []
需要说明一点,解包语法对所有的序列都成立,这就意味着对列表以及我们之前讲到的range函数返回的范围序列都可以使用解包语法。
a, b, *c = range(1, 10)
print(a, b, c) # 1 2 [3, 4, 5, 6, 7, 8, 9]
a, b, c = [1, 10, 100]
print(a, b, c) # 1 10 100
a, *b, c = 'hello'
print(a, b, c) # h ['e', 'l', 'l'] o
例子2:交换两个变量的值
交换两个变量的值是编程语言中的一个经典案例,在很多编程语言中,交换两个变量的值都需要借助一个中间变量才能做到,如果不用中间变量就需要使用比较晦涩的位运算来实现。
在Python中,交换两个变量a和b的值只需要使用如下所示的代码。
a, b = b, a
同理,如果要将三个变量a、b、c的值互换,b赋给a,c赋给b,a赋给c
a, b, c = b, c, a
元组和列表的比较
为什么Python中已经有了列表类型,还需要元组这样的类型呢?
1. 元组是不可变类型,不可变类型更适合多线程环境,因为它降低了并发访问变量的同步化开销。
2. 元组是不可变类型,通常不可变类型在创建时间和占用空间上面都优于对应的可变类型。使用sys模块的getsizeof函数来检查保存相同元素的元组和列表各自占用了多少内存空间。
使用timeit模块的timeit函数来看看创建保存相同元素的元组和列表各自花费的时间。
import sys
import timeit
a = list(range(1000000))
b = tuple(range(1000000))
print(sys.getsizeof(a), sys.getsizeof(b)) # 800056 800040
print(timeit.timeit('[1, 2, 3, 4, 5, 6, 7, 8, 9]')) # 0.030087999999523163
print(timeit.timeit('(1, 2, 3, 4, 5, 6, 7, 8, 9)')) # 0.006271100020967424
Python中的元组和列表是可以相互转换的
# 将元组转换成列表
info = ('喜羊羊', 175, True, '青青草原')
print(list(info)) # ['喜羊羊', 175, True, '青青草原']
# 将列表转换成元组
fruits = ['apple', 'banana', 'orange']
print(tuple(fruits)) # ('apple', 'banana', 'orange')
总结
列表和元组都是容器型的数据类型,即一个变量可以保存多个数据。列表是可变数据类型,元组是不可变数据类型,所以列表添加元素、删除元素、清空、排序等方法对于元组来说是不成立的。但是列表和元组都可以进行拼接、成员运算、索引和切片这些操作
恭喜你学会了元组,快去试试吧!!!