【python】Tuples元组

本文介绍了Python中的元组,包括元组的基本概念、不可变性、创建方式以及与其他数据结构(如列表、字典)的交互。还讨论了元组在交换赋值、函数返回值、可变数量参数等方面的应用,并通过实例展示了元组的灵活性和实用性。

基本介绍

元组是值的序列。 这些值可以是任何类型,并且它们由整数进行索引,因此在这方面元组非常类似于列表。 重要的区别在于元组是不可变的(immutable)。
在语法上,tuple 是一个以逗号分隔的值列表,虽然没有必要,但常常将元组括在括号内。

t = 'a', 'b', 'c'
type(t)
#tuple
t = ('a', 'b', 'c')
type(t)
#tuple

要用创建一个 只有一个元素的元组,必须包含一个最后的逗号:

t = 'a',
type(t)
#tuple

括号中的只有一个元素不是元组:

t = ('a')
type(t)
#str
t = ('a',)
type(t)
#tuple

创造一个空的元组:

t =tuple()
t
#()

如果参数是一个序列(字符串、列表或元组) ,结果是一个包含所有其中元素的元组:

t =tuple('mathilda')
t
#('m', 'a', 't', 'h', 'i', 'l', 'd', 'a')

大多数列表操作符也用于元组:

t =tuple('mathilda')
t[0]
#'m'
t[1:3]
#('a', 't')

但是如果试图修改元组的一个元素,会报错:

t[0] = 'A'
#TypeError: 'tuple' object does not support item assignment

因为元组是不可变的,所以不能修改元素。 但是可以用另一个元组替换一个元组(注意第一个要是元组不能是‘M’),语句生成一个新元组,然后命名为t。

t = ('M',) + t[1:]
t
#('M', 'a', 't', 'h', 'i', 'l', 'd', 'a')

关系运算符处理元组和其他序列:Python 从比较每个序列的第一个元素开始。 如果它们相等,则继续到下一个元素,依此类推,直到找到不同的元素。 不考虑后续元素(即使它们非常大)。

(1, 2, 3) < (1, 1, 100)
#false

元组的交换赋值

一般我们要交换两个变量的值,我们会这么写:

temp = a
a = b
b = temp

元组的交换则会更为简略:

a, b = b, a

左边是一个变量元组,右边是一个表达式元组,每个值都分配给其各自的变量,右边的所有表达式都在任何赋值之前进行计算。左边和右边的元素个数必须相同。
右边可以是任何类型的序列(字符串、列表或元组)。 例如,将一个电子邮件地址分割成一个用户名和一个域名,可以这样写:

email = "yrc.mathilda@gmail.com"
uname, doname = email.split("@")
#uname:'yrc.mathilda' doname:gmail.com

返回元组

严格地说,一个函数只能返回一个值,但是如果该值是一个元组,那么可以返回多个值。 例如,如果希望除以两个整数并计算商和余数,那么计算x//y和x%y是低效的,可以同时计算它们。

内置函数divmod接受两个参数并返回两个值(商和余数)组成的元组。 可以将结果存储为一个元组,也可以用元组的赋值分别储存结果:

t = divmod(10, 4)
t
#(2, 2)
a, b = divmod(10, 4)
#a = 2, b = 2

这是一个函数返回元组的例子:

def first_last(l):
    return l[0], l[-1]
first_last([1, 2, 3])
#(1, 3)

参数*

函数可以接受可变数量的参数。以为*开头的参数名称将参数收集到元组中。 比如说,

def first_last(*l):
    print(type(l))
    return l[0], l[-1]
first_last(1, 2, 3)
#<class 'tuple'>
#(1, 3)

*参数可以是任何名称,但是常规用args。
如果是一个元组,也可以用 * 来把它打散

t = (10, 4)
divmod(t)
#TypeError: divmod expected 2 arguments, got 1
divmod(*t)
#(2, 2)

许多内置函数比如max,min就是接受这种参数(Variable-length argument tuples)所以可以接收无数个参数

max(1, 2, 3, 4, 5, 6, 7, ...)

但是sum不可以

sum(1, 2, 3)
#TypeError: sum expected at most 2 arguments, got 3

参数**

*不能在像字典一样的对象中使用

def printall(*args):
    print(args)
printall(1, 2, 3)
#(1, 2, 3)
printall(1, 2, third = 3)
#TypeError: printall() got an unexpected keyword argument 'third'

为了获得字典一样的参数可以用**来获取

def printall(*args, **kwargs):
    print(args, kwargs)
printall(1, 2, 3)
#(1, 2, 3) {}
printall(1, 2, third = 3)
#(1, 2) {'third': 3}

题外话:a和d是等价的

d = dict(x=1, y=2)
a = {'x':1, 'y':2}
a == d
#True

更多的例子

print(1, 2, 3)
#等价于
print(*[1, 2, 3])
#为1 2 3, print([1, 2, 3])为[1, 2, 3]

def f(*args, **kwargs):
	print("ARGS", args)
	print("KWARGS", kwargs)
f(1, 2, x = 3, y = 4, z = 5)
#ARGS (1, 2)
#KWARGS {'x': 3, 'y': 4, 'z': 5}

list和tuple

zip是一个内置函数,它需要两个或多个序列,并将它们并在一起。

a = "abc"
b = (1, 2, 3)
zip(a, b)
#<zip at 0x7fe091401f08>

这样的结果是zip对象,但这个对象可以进行遍历,所以zip最常见的用途就是用在循环中

a = "abc"
b = (1, 2, 3)
for pair in zip(a, b):
    print(pair)
#('a', 1)
#('b', 2)
#('c', 3)

zip对象是一种迭代器,在某些方面与列表相似,但与列表不同的是,不能使用索引从迭代器中选择元素。
如果想使用列表操作符和方法,可以这样:

list(zip(a, b))
#[('a', 1), ('b', 2), ('c', 3)]
type(list(zip(a, b))[0])
#tuple

结果是一个元组列表。

如果序列的长度不相同,则结果是选取较短序列的长度。

list(zip('avbc', 'sdf'))
#[('a', 's'), ('v', 'd'), ('b', 'f')]

还可以这样

a = "abc"
b = (1, 2, 3)
for ch, num in zip(a, b):
    print(ch, num)
#a 1
#b 2
#c 3

如果需要遍历序列的元素及其索引,可以使用内置函数enumerate:
其结果是枚举对象,它迭代一系列对,每个对包含一个索引(从0开始)和一个来自给定序列的元素。

for index, ch in enumerate('abc'):
    print(index, ch)
#0 a
#1 b
#2 c

字典和tuple

字典有一个名为items的方法,它返回一个元组序列,其中每个元组是一个键值对。items的对象可以用于循环,在字典里的元素没有特定顺序。

d = {'a':1, 'b':3, 'c':10}
d.items()
#dict_items([('a', 1), ('b', 3), ('c', 10)])
for key, val in d.items():
    print(key, val)
#a 1
#b 3
#c 10

反过来,可以使用元组列表来初始化一个新的字典:

t = [('a', 1),('b', 3),('c', 10)]
dict(t)
#{'a': 1, 'b': 3, 'c': 10}

可以结合dict和zip非常简洁的创造字典:

dict(zip('abc', [1,2, 3]))
#{'a': 1, 'b': 2, 'c': 3}

字典中的update方法同样可以接收由tuple组成的list,并且添加到字典中。
在字典中使用tuple作为key是很普遍的,因为不能使用list
可以写:

d[a, b] = c
for a, b in d:
	print(a, b, d[a, b])

这样在循环中的ab只会取值d的key赋值给ab

<think> 我们正在讨论Python元组的使用方法,特别是如何用元组存储语句。 根据引用[1]和[2],元组是不可变的有序序列,可以存储不同类型的元素。我们可以将语句作为字符串存储在元组中。 例如,我们可以这样创建一个包含多个语句的元组: statements = ("Hello, world!", "Python is fun.", "Tuples are immutable.") 注意:如果元组只有一个元素,需要在元素后面加逗号,如:('single statement',) 另外,引用[3]提到元组比列表更轻量级,性能略优,且在缓存方面有优势。因此,如果我们有一组不会改变的语句,使用元组存储是高效的选择。 下面是一个示例代码,展示如何创建、访问元组中的语句: ```python # 创建一个包含多个语句的元组 statements = ( "Tuples are ordered, immutable collections of data.", "They are often used for heterogeneous data.", "This is a statement about tuples." ) # 访问元组中的第一个语句 first_statement = statements[0] print(first_statement) # 输出: Tuples are ordered, immutable collections of data. # 遍历元组中的所有语句 for s in statements: print(s) ``` 注意:由于元组不可变,我们不能修改、添加或删除元组中的语句。如果需要修改,应该使用列表,但如果不需修改,元组是更好的选择。 §§相关问题§§ 1. 元组和列表在存储语句时有哪些主要区别? 2. 如何从文件中读取语句并存储到元组中? 3. 元组不可变特性对存储语句有什么优势和限制? </think> ### Python中使用元组存储语句的方法 在Python中,元组tuple)作为不可变的有序序列,非常适合存储需要保护其完整性的语句或文本片段。以下是具体实现方法: #### 1. **基本存储方法** ```python # 创建包含多个语句的元组 statements = ( "Python元组是不可变的", "元组使用圆括号定义", "元组支持多种数据类型存储" ) # 访问第二个语句 print(statements[1]) # 输出:元组使用圆括号定义 ``` > 说明:直接使用圆括号`()`包裹字符串语句,多个语句用逗号分隔[^1][^2] #### 2. **包含特殊字符的语句存储** ```python # 存储含引号和格式的语句 formatted_statements = ( 'print("Hello World!")', r"正则表达式: \d+\.\d+", f"当前时间: {__import__('datetime').datetime.now().strftime('%H:%M')}" ) ``` #### 3. **混合数据类型存储** ```python # 存储语句及相关元数据 statement_record = ( "Python缓存小体积元组", # 语句文本 "性能优化", # 分类标签 2023, # 创建年份 True # 验证状态 ) ``` #### 4. **从外部源加载语句** ```python # 从文件加载语句到元组 with open('statements.txt') as f: statement_tuple = tuple(line.strip() for line in f) ``` #### 5. **单语句元组的特殊写法** ```python single_statement = ("这是唯一的语句",) # 必须保留逗号 ``` ### 性能与特性说明 1. **不可变性**:一旦创建无法修改,适合存储需要防篡改的语句[^1] 2. **内存效率**:比列表更轻量,小体积元组会被Python缓存复用[^3] 3. **访问速度**:索引访问比列表略快(约5-10%),特别适合只读场景[^3] 4. **安全特性**:可作为字典键使用,而列表不可以 > **最佳实践**:当存储的语句集合不需要修改且需要保护完整性时,优先选择元组而非列表
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值