Python中列表、序列和切片的区别是什么?

40

这些Python内置数据类型:列表(list)、序列(sequence)和切片(slice)之间有什么区别?我认为,它们都基本上代表C++和Java所称的数组


9
Python文档有定义 - SilentGhost
5个回答

90

你在问题中混淆了很多不同的东西,所以我会回答一个不同的问题。

你现在问的是Python中最重要的接口之一:iterable - 它基本上是任何可以像for elem in iterable这样使用的东西。

iterable有三个后代:sequencegeneratormapping

  • 序列(sequence)是具有随机访问功能的可迭代对象。您可以请求序列中的任何项,而无需消耗其前面的项。通过此属性,您可以构建slices,它们一次可以给您多个元素。切片可以给出子序列:seq[from:until]和每n个项:seq[from:until:nth]listtuplestr都是序列。

  • 如果访问是通过键而不是整数位置完成的,则有一个映射(mapping)dict是基本映射。

  • 最基本的可迭代对象是一个生成器(generator)。它不支持随机访问,因此也不支持切片。您必须按照给定的顺序消耗所有项目。生成器通常只在迭代它们时创建其项目。创建generators的常见方法是使用生成器表达式。它们看起来与列表推导相同,只不过要用圆括号,例如(f(x) for x in y)。调用使用yield关键字的函数也会返回一个生成器。

适用于所有可迭代对象的常见适配器是迭代器(iterator)迭代器(iterators)具有与它们支持的最基本类型相同的接口,即generator。通过在可迭代对象上调用iter来明确地创建它们,并且在各种循环结构中隐式使用它们。


我喜欢这个答案中提到生成器的部分。想想“懒惰”和“无限”。 - 拇指 muzhi.com
1
点赞支持“最基本的可迭代对象是生成器”。 - C S

17
  • list 不仅是普通的数组。你可以不指定数量来初始化它们。你可以 append/push 元素到列表中,你可以从列表中 remove/pop/del元素,你可以将不同类型的对象存储在列表中(例如: [1,'e', [3]] ),你可以有递归列表...... 以及你可以对列表进行切片操作,也就是得到一个只包含其中一部分元素的新列表。
  • slice 是一种“幕后”使用的对象类型,用于处理扩展切片,在 a[start:stop:step] 格式中,可以通过 help(slice) 查看更多信息。

“Sequence” 不是一个对象,而更像是一些对象(如 list)实现的非正式接口。


2
也许更好的C++类比是std::vector,只不过是异构的。 - Peter Milley

10

列表是一种序列,但不是所有序列都是列表。序列是任何支持序列接口(“协议”)的类型,这是通过鸭子类型而不是严格的继承层次结构来完成的。请注意,序列是容器,但并非所有容器都是序列。(序列是连贯的!)

参见http://docs.python.org/library/stdtypes.html#sequence-types-str-unicode-list-tuple-buffer-xrange

切片对象通常是通过语法糖(foo [2:5])隐式创建,并提供给容器类型的特殊方法(例如__getitem__),您可以重写此方法。除非创建自己的序列/容器,否则通常不必处理切片。

参见http://docs.python.org/reference/datamodel.html#specialnames

列表类似于数组。我不确定,但我认为它在cPython中作为动态扩展数组实现。但是,界面使其更像C++ STL Vector而不仅仅是普通的数组。


9
  • 列表是一种序列类型,类似于数组。

  • 序列类型描述了一个功能上的超集:

有六种序列类型:字符串、Unicode 字符串、列表、元组、缓冲区和 xrange 对象。

  • 切片是子数组(或子字符串)的表示方法。

阅读更多... http://docs.python.org/glossary.html


2

严格来说,切片是一种表示索引范围的类型,例如起始位置、结束位置和步长。切片根本不是容器类型。你可以使用切片来索引列表,得到一个新列表,它是原始列表的子列表副本。

列表与C++数组的区别在于它们是异构的;元素不需要是相同的类型。正如MYYN已经指出的那样,“序列”并不是Python的一种类型,而是各种内置类型的描述。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接