Python 元组与列表:异同,解释

已发表: 2022-08-08

在本指南中,您将了解 Python元组列表之间异同。 您还将了解何时应该使用元组。

列表和元组都是 Python 中的内置数据结构。 它们可用于存储元素的集合。

从支持索引和切片到包含异构数据类型,元组和列表似乎具有相似的功能。 因此,了解两者的异同可以帮助您决定使用哪种数据结构。

让我们开始。

您可以启动 Python REPL 并按照本教程进行操作。 您还可以使用 Geekflare 的在线 Python 编辑器进行编码。

Python 元组与列表:有什么相似之处?

让我们从学习列表和元组之间的相似性开始。 为了促进更好的学习,我们提供了列表和元组的示例。

python-tuple-vs-list

#1 。 Python 可迭代对象

在 Python 中,列表用一对方括号括起来,而元组用括号括起来。 您还可以将元组创建为由逗号分隔的一组值(不带括号)。

它们都是可迭代的; 因此您可以使用for循环遍历它们。

下面的代码单元显示了如何遍历列表。

 nums = [2,6,7,10] print(f"Type of nums is {type(nums)}") for num in nums: print(num) # Output Type of nums is <class 'list'> 2 6 7 10

如下所述,您还可以使用循环遍历元组

nums = (2,6,7,10) # Note: nums = 2,6,7,10 is a valid tuple as well. If needed, run a quick check! print(f"Type of nums is {type(nums)}") for num in nums: print(num) # Output Type of nums is <class 'tuple'> 2 6 7 10

#2 。 支持从其他序列创建

列表和元组之间的下一个相似之处是它们可以从现有的序列(例如字符串)创建。

 sample_str = "Coding!"

以下代码单元显示list(string)如何返回一个列表,其列表项是字符串中的字符。

 list_from_str = list(sample_str) print(list_from_str) # Output ['C', 'o', 'd', 'i', 'n', 'g', '!']

类似地,可以使用tuple(sequence)从字符串或其他序列创建元组。 下面的代码单元显示了如何做到这一点。

 tuple_from_str = tuple(sample_str) print(tuple_from_str) # Output ('C', 'o', 'd', 'i', 'n', 'g', '!')

#3 。 支持索引和切片

Python 支持零索引,其中第一个元素在索引 0 处,第二个在索引 1 处,依此类推。 Python 还支持负索引,其中最后一个元素位于索引 -1,倒数第二个元素位于索引 -2,依此类推。

 list_from_str = ['C', 'o', 'd', 'i', 'n', 'g', '!'] print(list_from_str[1]) # o

索引 -2 处的项目是倒数第二个项目“g”。

 tuple_from_str = ('C', 'o', 'd', 'i', 'n', 'g', '!') print(tuple_from_str[-2]) # g

当您想要处理列表或元组的一小部分时,可以使用切片。 list[start:end] 返回从索引 start 开始并一直延伸到 end – 1 的列表切片。 start 的默认值为 0,end 是可迭代对象中的最后一个元素。

您可以使用相同的语法对元组进行切片。 让我们创建之前创建的列表和元组的切片。

 list_from_str = ['C', 'o', 'd', 'i', 'n', 'g', '!'] print(list_from_str[0:5]) ['C', 'o', 'd', 'i', 'n']

除了开始值和结束值之外,您还可以指定步长值。 tuple(start:end:step)返回从startend - 1的元组切片,步长为step

 tuple_from_str = ('C', 'o', 'd', 'i', 'n', 'g', '!') print(tuple_from_str[::2]) ('C', 'd', 'n', '!')

在这里,我们将步长值设置为 2。因此切片包含每隔一个元素。

#4 。 多种数据类型的集合

在我们考虑的示例中,列表和元组中的所有项目都具有相同的数据类型。

但是,您可以将不同数据类型的值存储在单个列表或元组中。

student_list下面的代码片段包含一个字符串形式的学生姓名、整数形式的年龄和浮点数形式的安全标记。

 student_list = ["John",22,96.5] for item in student_list: print(f"{item} is of type {type(item)}") # Output John is of type <class 'str'> 22 is of type <class 'int'> 96.5 is of type <class 'float'>

我们可以为元组想出一个类似的例子。

 student_tuple = ("Jane",23,99.5) for item in student_tuple: print(f"{item} is of type {type(item)}") # Output Jane is of type <class 'str'> 23 is of type <class 'int'> 99.5 is of type <class 'float'>

#5 。 支持会员测试

列表和元组都允许您对某些项目的存在执行成员资格测试。 如果要检查列表或元组中是否存在特定项目,可以使用in运算符。

如果iterable包含item ,则 iterable 中的表达式item in iterable计算结果为True ; 否则, False

 "Alex" in student_list # False "Jane" in student_tuple # True

到目前为止,您已经了解了 Python 中列表和元组之间的相似之处。 接下来,让我们了解这两种数据结构之间的关键区别。

Python 元组与列表:有什么区别?

#1 。 Python 中列表的可变性和元组的不变性

Python 中列表和元组之间最关键的区别是元组不可变的。 这意味着您不能就地修改元组。

️这是一个例子。

 tuple1 = ("Java","Python","C++") tuple1[0] = "Rust" # Output ----> 2 tuple1[0] = "Rust" TypeError: 'tuple' object does not support item assignment

列表是一种可变数据结构,因此我们可以通过更改特定索引处的项目来修改列表,如下面的代码单元所示。

 list1 = ["Java","Python","C++"] list1[0] = "Rust" print(list1) # Output ['Rust', 'Python', 'C++']

#2 。 可变长度列表与固定长度元组

Python 列表是一种可变长度的数据结构。

您可以执行以下操作:

  • 将项目添加到列表末尾
  • 将另一个列表中的项目添加到当前列表的末尾
  • 从列表中删除特定索引处的项目
list1 = [2,3,4,5] # add an item to the end list1.append(9) print(list1) # add items from list2 to the end of list1 list2 = [0,7] list1.extend(list2) print(list1) # remove an item from list1 list1.pop(0) print(list1)

️ 上述代码片段的输出。

 # Output [2, 3, 4, 5, 9] [2, 3, 4, 5, 9, 0, 7] [3, 4, 5, 9, 0, 7]

元组是固定长度的数据结构。 因此,您不能在现有元组中添加或删除元素。 但是您可以重新定义元组以包含不同的元素。

 tuple1 = (2,4,6,8) tuple1 = (1,8,9) print(tuple1) # Output (1, 8, 9)

#3 。 内存大小

现在,我们将在上一节中学习的基础上进行构建:列表是一个可变长度的数据结构。

最初定义列表时,会在内存中为其分配特定大小。 现在,当您使用append()extend()方法修改列表时,应该分配额外的内存来存储添加的元素。 这种分配几乎总是比您添加的项目数多。

因此需要跟踪列表中的项目数和分配的空间。 此外,由于列表是可变长度的,因此有一个指针指向列表项的地址。 结果,长度为k的列表比具有相同k个元素的元组占用更多的内存。

这是一个简单的例子。

python-tuple-vs-list-size

您可以在 Python 对象上使用内置 sys 模块的getsizeof()方法来获取内存中对象的大小。

 import sys list1 = [4,5,9,14] list_size = sys.getsizeof(list1) print(f"Size of list:{list_size}") tuple1 = (4,5,9,14) tuple_size = sys.getsizeof(tuple1) print(f"Size of tuple:{tuple_size}")

对于相同数量和值的元素,列表比元组占用更多内存,如下面的输出所示。

 # Output Size of list:104 Size of tuple:88
元组-vs-list-python

什么时候应该使用 Python 元组?

从 Python 列表和元组的异同可以看出,如果需要可变集合,就应该使用列表

但是什么时候应该使用元组呢?

我们将在本节中讨论。

#1 。 只读集合

每当您希望集合不可变时,都应将其定义为元组。 假设color = (243,55,103)一个元组,其中包含对应于颜色阴影的 RGB 值。 将颜色定义为元组可确保它不能被修改。

本质上,当您需要一个集合是只读的:在程序期间不应该修改值时,您应该考虑使用元组。 这将防止对值的意外修改。

#2 。 字典键

例如,您使用列表项key_list作为键创建字典。 您可以使用dict.fromkeys()方法从列表创建字典。

 key_list = list("ABCD") dict.fromkeys(key_list) {'A': None, 'B': None, 'C': None, 'D': None}

假设您在创建字典之前修改列表以包含“D”作为第一个元素(索引 0)。

现在,字典键“A”会发生什么?

如果您尝试从key_list创建字典并访问与键 'A' 对应的值,则会遇到KeyError

 key_list[0] = 'D' dict.fromkeys(key_list)['A'] --------------------------------------------------------------------------- KeyError Traceback (most recent call last) <ipython-input-31-c90392acc2cf> in <module>() ----> 1 dict.fromkeys(key_list)['A'] KeyError: 'A'

字典的键应该是唯一的。 所以你不能有第二个'D'作为键。

 dict.fromkeys(key_list) {'B': None, 'C': None, 'D': None} # A is no longer a key.

如果您改为使用元组,则不可能进行此类修改,并且您不太可能遇到错误。 因此,您应该更喜欢使用元组的项目作为键来创建字典。

 key_tuple = tuple("ABCD") dict.fromkeys(key_tuple) {'A': None, 'B': None, 'C': None, 'D': None} key_tuple[0] = 'D' --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-12-2cecbefa7db2> in <module>() ----> 1 key_tuple[0] = 'D' TypeError: 'tuple' object does not support item assignment

#3 。 函数参数

元组的不变性也使得它们适合作为函数参数传入。

考虑以下函数find_volume() ,它返回给定尺寸的长方体体积:长度、宽度和高度。

 def find_volume(dimensions): l,b,h = dimensions return l*b*h

假设这些维度在名为dimensions的列表中可用。 以dimensions为参数调用find_volume()会返回体积。

 dimensions = [2,8,5] find_volume(dimensions) 80

您始终可以更改存储在列表中的维度。

 dimensions = [20,8,5] find_volume(dimensions) 800

但是,有时您需要这些值保持不变并抵制修改。 那时您应该考虑将参数存储为元组并在函数调用中使用它们。

#4 。 函数的返回值

在 Python 中,您会在函数的返回值中遇到元组。 当你从一个函数返回多个值时,Python 隐式地将它们作为一个元组返回。

考虑以下函数return_even()

 def return_even(num): even = [i for i in range(num) if (i%2==0)] return even,len(even)
  • 它需要一个数字num作为参数
  • 它返回区间[0,num)中的偶数列表和该列表的长度。

让我们设置num 20 的值并调用该函数。

 num = 20

调用return_even()会返回一个元组中的两个值。 您可以使用函数调用作为验证参数来调用type()函数。

 type(return_even(num)) # <class 'tuple'>

您可以打印出返回值以验证它是一个元组,其中包含偶数列表作为第一项,列表的长度作为第二项。

 print(return_even(num)) ([0, 2, 4, 6, 8, 10, 12, 14, 16, 18], 10)

由于元组中有两个项目,您可以将它们解包为两个变量,如下所示。

 even_nums, count = return_even(num) print(even_nums) print(count) [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] 10

结论

我希望本教程提供了 Python 元组与列表的全面比较。

让我们用一个快速的总结来结束本教程:

  • 列表和元组是 Python 中的内置数据结构。
  • 相似之处:可迭代,支持索引,切片,不同的数据类型,以及用于成员资格测试的运算符。
  • 关键区别:列表是可变的,而元组是不可变的。
  • 其他区别:元组的固定长度和列表的可变长度,元组的内存更小。
  • 什么时候应该使用元组? 对于不可变集合、字典键和函数参数。

接下来,查看 Python 项目以进行练习和学习。 或者学习从 Python 列表中删除重复项的方法。 快乐学习! 然后,快乐编码!