欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

04 元组(源于Datawhale)

程序员文章站 2022-06-22 08:05:09
在[1]中提及到“python将不能修改的值称为不可变的,不可变的列表称为元组。使用圆括号来标识,可以用索引去访问元素"「元组」定义语法为:(元素1, 元素2, ..., 元素n)它有两个特征:(1)小括号把所有元素绑在一起(2)逗号将每个元素一一分开1 元组和创建元组和列表类似,不过就像前面所说,列表是可以修改可以变的,而元组不行;并且列表是用中括号进行标识的,元组是用小括号,或者不用(不过一般情况是会用小括号的,为了可读性),字典是用花括号;和列表一样也可以用整数来对它进行索引 (index...

[1]中提及到“python将不能修改的值称为不可变的,不可变的列表称为元组。使用圆括号来标识,可以用索引去访问元素"
「元组」定义语法为:(元素1, 元素2, ..., 元素n)
它有两个特征:
(1)小括号把所有元素绑在一起
(2)逗号将每个元素一一分开

1 元组和创建

元组和列表类似,不过就像前面所说,列表是可以修改可以变的,而元组不行;并且列表是用中括号进行标识的,元组是用小括号,或者不用(不过一般情况是会用小括号的,为了可读性),字典是用花括号;和列表一样也可以用整数来对它进行索引 (indexing) 和切片 (slicing);此外要注意当元组中只包含一个元素时,需要在元素后面添加逗号,否则括号会被当作运算符使用。

t1 = (1, 10.31, 'python') # 加了括号的元组
t2 = 1, 10.31, 'python' # 不加括号的元组
print(t1, type(t1))
# (1, 10.31, 'python') <class 'tuple'>
print(t2, type(t2))
# (1, 10.31, 'python') <class 'tuple'>

tuple1 = (1, 2, 3, 4, 5, 6, 7, 8)
print(tuple1[1])  # 2 索引,在位置1上的是什么元素
print(tuple1[5:])  # (6, 7, 8) 切片,从XX到XXX
print(tuple1[:5])  # (1, 2, 3, 4, 5)
tuple2 = tuple1[:] # 浅拷贝
print(tuple2)  # (1, 2, 3, 4, 5, 6, 7, 8)

x = (1) # 单个元素没有加逗号只有小括号是tuple还是int?
print(type(x))  # <class 'int'>
x = 2, 3, 4, 5 # 多个元素加了逗号没有小括号是tuple吗?
print(type(x))  # <class 'tuple'>
x = [] # 空列表
print(type(x))  # <class 'list'>
x = () # 空元组,没有逗号,也没有单个元素
print(type(x))  # <class 'tuple'>
x = (1,) # 单元素加逗号以及小括号是元组吗?
print(type(x))  # <class 'tuple'>

# 对应上面的一起理解,没有加逗号的单个元素带个小括号是int
print(8 * (8))  # 64
print(8 * (8,))  # (8, 8, 8, 8, 8, 8, 8, 8)

上面的有助于对于元组概念的理解,如单元素、逗号、小括号、空元组、元组的切片和索引、浅拷贝等。
不过对于此处的元组乘法还是不太理解

print(3*[3,6]) # [3, 6, 3, 6, 3, 6]
print(3*(1,2)) # (1, 2, 1, 2, 1, 2)

创建一个二维元组

# 创建一个二维元组
x = (1, 10.31, 'python'), ('data', 11)
print(x)
# ((1, 10.31, 'python'), ('data', 11))
print(type(x))
# <class 'tuple'>
y=((1,2,3,4),(5,6,7))
print("y:",y,"type(y):",type(y))
# y: ((1, 2, 3, 4), (5, 6, 7)) type(y): <class 'tuple'>

# 关于二维元组的索引
print(x[0])
# (1, 10.31, 'python')
print("x[0][0]:",x[0][0],"x[0][1]:",x[0][1],"x[0][2]:",x[0][2])
# x[0][0]: 1 x[0][1]: 10.31 x[0][2]: python
print(x[1])
# ('data', 11)
print("x[1][1]:",x[1][1])
# x[1][1]: 11

# 关于二维元组的切片
print(x[0][0:2])
# (1, 10.31)

2 更新和删除一个元组

元组有不可更改的性质,因此不能直接给元组的元素赋值,但是只要元组中的元素可更改 (mutable),那么我们可以直接更改其元素,注意这跟赋值其元素不同。
在下面的例子中,第一个例子加入了'wednesday',,注意有引号和逗号。
目前感觉这个标题不太合适,前者是加了个元素,后者是修改,暂时体会不到更新和删除~

week = ('Monday', 'Tuesday', 'Thursday', 'Friday')
week = week[:2] + ('Wednesday',) + week[2:]
print(week)  # ('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday')

t1 = (1, 2, 3, [4, 5, 6])
print(t1)  # (1, 2, 3, [4, 5, 6])
t1[3][0] = 9
print(t1)  # (1, 2, 3, [9, 5, 6])

3 元组相关的操作符

[2]列表也讲过类似的知识点,
等号操作符:==,只有成员、成员位置都相同时才返回True。
连接操作符 +
重复操作符 *(列表拼接有两种方式,用+*,前者首尾拼接,后者复制拼接。)
成员关系操作符 innot in

t1 = (123, 456)
t2 = (456, 123)
t3 = (123, 456)

# 关于等号操作符,只有成员、成员位置都相同时才返回True
print(t1 == t2)  # False
print(t1 == t3)  # True

# 关于连接操作符,把两个元组连接起来
t4 = t1 + t2
print(t4)  # (123, 456, 456, 123)

# 关于重复操作符
t5 = t3 * 3
print(t5)  # (123, 456, 123, 456, 123, 456)
# 前者是赋予了新值t5,后者是在原来的基础上修改
t3 *= 3
print(t3)  # (123, 456, 123, 456, 123, 456)

# 成员操作符
print(123 in t3)  # True
print(456 not in t3)  # False

4 内置方法

元组大小和内容都不可更改,因此只有 countindex 两种方法。
想到了上面谈的切片和索引

t = (1,1, 10.31, 'python')
print(t.count(1))  # 2
print(t.index(10.31))  # 2

5 解压元组

解压(unpack)一维元组(有几个元素在括号定义几个变量)


# 解压一维元组
t = (1, 10.31, 'python')
(a, b, c) = t
print(type(t))
# <class 'tuple'>
print(a, b, c)
# 1 10.31 python
print(type(a))
# <class 'int'>

解压二维元组(按照元组里的元组结构来定义变量)

# 解压二维元组
t = (1, 10.31, ('OK', 'python'))
(a, b, (c, d)) = t
print(a, b, c, d)
# 1 10.31 OK python

只想要元组其中几个元素,用通配符「*」,英文叫 wildcard,在计算机语言中代表一个或多个元素。把多余变量给与rest
下面三大行代码,前两份一者有括号一者没有,第三份代码是试验下把rest换成zl如何

t = 1, 2, 3, 4, 5
a, b, *rest, c = t
print(a, b, c)  # 1 2 5
print(rest)  # [3, 4],rest代表了其他元素
print(type(rest)) # <class 'list'>
print("*rest1:",*rest) # *rest1: 3 4
# print("type(*rest1):",type(*rest)) TypeError: type() takes 1 or 3 arguments

t = (1, 2, 3, 4, 5)
(a, b, *rest, c) = t
print(a, b, c)  # 1 2 5
print(rest)  # [3, 4],rest代表了其他元素
print(type(rest)) # <class 'list'>
print("*rest2:",*rest) # 3 4

t = (1, 2, 3, 4, 5)
(a, b, *zl, c) = t
print(a, b, c)  # 1 2 5
print(zl)  # [3, 4],zl代表了其他元素
print(type(zl)) # <class 'list'>

如果不在乎 rest 变量,那么就用通配符「*」加上下划线「_」

t = 1, 2, 3, 4, 5
a, b, *_ = t
print(a, b)  # 1 2,*_代表了其他元素
print(*_) # 3 4 5
# print(type(*_)) 报错:type.__new__() argument 1 must be str, not int
print(_) # [3, 4, 5]
print(type(_)) # <class 'list'>

t = 1, 2, 3, 4, 5
a, b, *_ ,c= t
print(a, b, c)  # 1 2 5,*_代表了其他元素
print(*_) # 3 4
# print(type(*_)) 报错:type() takes 1 or 3 arguments
print(_) # [3, 4]
print(type(_)) # <class 'list'>

目前看来,*rest*_有什么不同?

6 练习题

1、元组概念
写出下面代码的执行结果和最终结果的类型

(1, 2)*2
(1, )*2
(1)*2
print((1, 2)*2)
# (1, 2, 1, 2)
print((1, )*2)
# (1, 1)
print((1)*2)
# 2

前者是tuple,最后一个是int
2、拆包过程是什么?

a, b = 1, 2

上述过程属于拆包吗?
以上应该是是赋值吧?
可迭代对象拆包时,怎么赋值给占位符

[1]https://blog.csdn.net/leileixiang/article/details/107521000
[2]https://editor.csdn.net/md/?articleId=107582386
[3]https://github.com/datawhalechina/team-learning-program/blob/master/Python-Language/07.%20%E5%85%83%E7%BB%84.md

本文地址:https://blog.csdn.net/leileixiang/article/details/107637077