龙空技术网

Python索引技巧

IT老周 109

前言:

现时咱们对“python索引值”可能比较讲究,各位老铁们都需要分析一些“python索引值”的相关资讯。那么小编也在网摘上搜集了一些对于“python索引值””的相关资讯,希望你们能喜欢,朋友们一起来学习一下吧!

能够在Python中高效地分割序列(例如列表、字符串和元组)是编程时最关键的技能之一。幸运的是,python提供了索引语法,极大地简化了切片过程,使其更加直观。

在本教程中,我们将首先回顾如何索引序列,然后介绍序列的切片,特别是列表和字符串。此外,我们将介绍切片列表和切片字符串之间的一些重要区别,然后介绍列表中的切片赋值,最后看看在Python中使用索引语法时到底发生了什么。

为序列编制索引

在开始切片之前,我们简要回顾一下如何索引序列中的元素(特别是列表)。

请记住,我们可以通过使用方括号中的索引来访问列表中的各个元素。看看下面的数字列表:

num_list = [0,5,10,15,20,25,30,35,40]            0,1, 2, 3, 4, 5, 6, 7, 8           -9,-8,-7,-6,-5,-4,-3,-2,-1

序列中元素的索引是它在该序列中的位置。在上面的例子中,我们有一个数字列表num_list,该列表下面的数字表示相应元素的索引。

我们可以从开始(从左边)开始索引序列,从索引0开始为正索引,或者从序列结尾(从右边)开始为负索引,从索引-1开始。

换句话说,如果我们想num_list列表中检索数字10(或第三个元素),可以使用其正索引2或负索引-7:

num_list[2] #10# 或者num_list[-7]#10

如果要获得列表中的最后一个数字,即40,可以使用索引8或-1:

num_list[8]#40# 或者num_list[-1]#40

或者可以使用len()函数,如下所示:

num_list[len(num_list)-1]#40

如果使用的索引值不在列表中或超出范围,则会收到IndexError:

num_list[12]#IndexError: list index out of rangenum_list[-12]#IndexError: list index out of range

现在我们已经回顾了如何使用正索引和负索引对序列进行索引,接下来看看切片。

切片序列

我们刚刚看到了如何使用索引从列表中检索单个元素。另一方面,切片允许我们从序列中获得一部分,比如一个列表或字符串。

有时为了理解切片,可以想象索引指向元素之间,而不是元素本身。尽管这只在步长为正的情况下才有用,也就是说从左到右进行切片。稍后将详细介绍步长。

num_list = [0,5,10,15,20,25,30,35,40] +---+---+----+----+----+----+----+----+----+ | 0 | 5 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | +---+---+----+----+----+----+----+----+----+ 0   1   2    3    4    5    6    7    8    9-9  -8  -7   -6   -5   -4   -3   -2   -1

切片序列的语法如下:

variable[start:stop:step]

为了对序列进行切片,我们需要使用方括号内的冒号。换句话说,[方括号]中的冒号(:)是切片符号。尽管我们可以在括号中提供三个可能的值(start,stop,step),但我们实际上不必提供所有这三个值,除非需要,具体情况我们将在下面看到。

下面看一些例子。

指定开始和终止位置

我们可以对序列(如列表)进行切片的一种方法是指定开始位置和终止位置。换句话说,如果想要列表中两个特定点之间的所有元素,我们可以使用以下格式:

variable[start:stop]

variable[start:stop]返回变量中从位置开始到但不包括终止位置的部分。

例如,如果我们想获得从索引2到索引6(包括索引6)的所有元素,我们可以按如下方式进行:

num_list = [0,5,10,15,20,25,30,35,40]num_list[2:7]#[10,15,20,25,30]

请注意,开始位置是包含的,而终止位置是不包含的。因此,我们从下标2开始,也就是数字10,一直到但不包括下标7,它是下标6处的数字30。

可以把start,stop想象成元素之间的索引(如上所示)。因为没有提供步长值,所以默认的步长值是1。因此,我们从索引2开始,然后向索引3移动1步,然后再向索引4移动1步,以此类推。换句话说,因为步长值是正的,所以在对列表进行切片时,我们将下标增加1(向右移动)。

仅指定开始位置

如果想从一个特定的位置开始并遍历整个列表,那么我们只需要提供开始位置。

variable[start:]

variable[start:]返回变量中从位置start开始到序列结束的部分。

例如,如果我们想通过整个列表从第二个索引中检索所有元素,可以使用以下代码:

num_list = [0,5,10,15,20,25,30,35,40]num_list[2:]#[10,15,20,25,30,35,40]

如我们所见,如果我们只在冒号之前提供一个索引,那么它将是开始索引,我们将获得列表中的其余元素(因为step值默认是1)。

仅指定终止位置

如果想从列表的开头开始,到某个位置终止,那么只需要提供stop值。

variable[:stop]

**variable[:stop]**返回从序列开头开始的变量部分,直到但不包括位置stop。

例如,我们要检索从列表开始到索引7(包括索引7)的所有元素,可以按如下操作:

num_list = [0,5,10,15,20,25,30,35,40]num_list[:8]# 或者num_list[:-1]#[0,5,10,15,20,25,30,35]

因此,如果没有为开始位置提供数字,则假定我们要从索引0开始。要检索索引7之前的所有元素,就设置stop值为8(因为8是不被包含在内的)。也可以使用-1作为终止位置。

使用正索引和负索引

我们还可以混合正索引和负索引。例如,如果要检索索引2到索引7(包括索引7)之间的所有元素,可以按如下操作:

num_list = [0,5,10,15,20,25,30,35,40]num_list[2:8]# 或者num_list[2:-1]# 或者num_list[-7:-1]# 或者num_list[-7:8]#[10,15,20,25,30,35]

请注意,在所有情况下,终止位置都在开始位置的右侧,因为我们使用的是正的步长值。换句话说,相对于开始位置,终止位置必须在步长值的方向上。如果步长值为正,则终止位置必须在开始位置的右侧。如果步长值为负,则终止位置必须在开始位置的左边,稍后再谈。

检索整个列表

我们还可以通过使用没有开始位置或终止位置的冒号来检索整个列表。

variable[:]

variable[:]返回整个序列。

num_list = [0,5,10,15,20,25,30,35,40]num_list[:]# 或者num_list[::]#[0,5,10,15,20,25,30,35,40]
步长值

到目前为止,我们只指定了start或stop值,从start值开始,在stop值之前结束。但是如果我们不想要这两点之间的所有元素呢?如果想要其他元素呢?这就是步长值的意义。

假设我们需要列表中的其他所有值,从索引0开始。或者我们只希望元素的索引为偶数。可以使用步长值:

variable[::step]

num_list = [0,5,10,15,20,25,30,35,40]num_list[::2]#[0,10,20,30,40]

因为我们没有指定start或stop值,所以它假设我们要从序列的开头开始并遍历整个列表。所以它从索引0开始,然后转到索引2(因为步长是2),然后转到索引4,依此类推。

前面提到,相对于开始位置,终止位置必须与步长值位于同一方向。换句话说,如果步长值为正,这意味着我们正在向右移动,那么终止位置必须在开始位置的右边。如果步长值为负,则终止位置必须在开始位置的左侧。否则,将返回空列表:

num_list = [0,5,10,15,20,25,30,35,40]num_list[8:5]#[]num_list[8:5:-1]#[40,35,30]

可以看到,在这两个例子中,开始位置是8,终止位置是5,所以终止位置在开始位置的左边。

在第一个示例中,步长值为+1。因为终止位置在开始位置的左边,步长值为正,所以返回一个空列表,因为不能向终止位置的方向移动。但是,在第二个示例中,我们将步长值更改为-1。因此,从索引8开始,即40,将1个索引向负或左移动到索引7,即35,然后移动到索引6,即30。我们不去索引5,因为终止位置是不包含的。

反转顺序

也许步长值最重要的实际应用是反转序列。例如,如果我们想以相反的顺序检索整个列表,可以使用-1作为步长值:

num_list[::-1]#[40,35,30,25,20,15,10,5,0]

因为我们没有指定开始或终止位置,所以将检索整个序列。但是,由于步长值是-1,它以相反的顺序获得元素。

如果终止位置大于序列中可用的最高索引,该怎么办?或者开始和/或终止位置是否超出范围?换言之,如果我们要的东西比现在的多会怎么样?

如果尝试以下操作:

num_list = [0,5,10,15,20,25,30,35,40]num_list[2:12]#[10,15,20,25,30,35,40]

正如我们所看到的,即使请求的项比序列中的项多,它也只返回存在的元素,不会给我们一个错误。相反,如果尝试索引超出范围的单个元素(而不是切片),那么我们将得到一个IndexError,正如前面看到的那样。

num_list[12]#IndexError
切片字符串

索引和切片对字符串的工作方式也是一样的。同样,如果使用正的步长值,我们可以想象字符之间的索引,如下所示:

 word = 'Python'  +---+---+---+---+---+---+ | P | y | t | h | o | n | +---+---+---+---+---+---+ 0   1   2   3   4   5   6-6  -5  -4  -3  -2  -1

因此,为了通过切片获得子串'yt',我们可以这样做:

word[1:3]#'yt'

要反转字符串,可以使用步长值-1:

word[::-1]#'nohtyP'
回文示例

让我们用学到的知识来解决一个非常常见的python编码问题。我们要编写一个函数,它接收一个字符串,并返回该字符串是否为回文。如果字符串的反转与原始字符串相同,则该字符串为回文。例如,“civic”是回文,但“radio”不是,因为“radio”的反转是“oidar”,而“civic”的反转是“civic”。

刚刚学习了如何使用步长值-1来反转序列。因此可以很容易地编写一个函数来实现这一点,如下所示:

isPalindrome(word):    return word == word[::-1]

就这样!表达式word==word[::-1]的计算结果为True或False。如果传入的字符串等于它的反转,则表达式的计算结果为True,并返回True。如果传入的字符串不等于其反转,则表达式的计算结果为False,并返回False。

isPalindrome('civic')# TrueisPalindrome('radio')# False
切片赋值

回想一下,列表在python中是可变的对象。换言之,它们可以改变。因此,我们可以使用切片赋值操作来就地修改或编辑列表。

替换

num_list = [0,5,10,15,20,25,30,35,40]num_list[2:5] = [1,2,3]num_list#[0,5,1,2,3,25,30,35,40]num_list[2:5] = [1,2,3,4,5,6]num_list#[0,5,1,2,3,4,5,6,25,30,35,40]

注意如何用更多或更少的元素替换列表的一部分。

删除

我们还可以使用del关键字删除列表的一部分或部分:

num_list = [0,5,10,15,20,25,30,35,40]del num_list[2:5]num_list#[0,5,25,30,35,40]

注意:字符串和元组是不可变的。因此不能像使用列表那样编辑或修改它们。

切片字符串与列表

切片列表将返回该列表的副本,而不是对原始列表的引用。

可以在这里看到:如果将列表切片赋值给另一个列表,因为列表切片返回的是一个副本而不是对原始列表的引用,所以我们可以修改新列表(因为列表是可变的),而不影响原始列表:

num_list = [0,5,10,15,20,25,30,35,40]# 将num_list的一部分赋值给new_listnew_list = num_list[2:5]new_list#[10,15,20]# 将新列表的第三个元素替换为3new_list[2] = 3# new_list 改变new_list#[10,15,3]# 数字列表保持不变num_list#[0,5,10,15,20,25,30,35,40]

相反,当切片一个字符串时,返回对原始字符串对象的引用,而不是一个副本。记住,字符串在Python中是不可变的。

我们可以使用Python的identity操作符(is)和equality操作符(==)来确认切片列表会返回一个副本或与原始列表不同的对象,但是切片字符串会返回对原始字符串对象的引用:

Lists:num_list = [0,5,10,15,20,25,30,35,40]num_list == num_list[:]#Truenum_list is num_list[:]#FalseStrings:word = 'Python'word == word[:]#Trueword is word[:]#True

相等运算符(==)检查值是否相等。identity操作符(is)检查两个变量是否指向内存中的同一个对象。

slice函数

内置的slice函数实际上是用来创建slice对象的。

slice(stop)

slice(start, stop[,step])

slice函数可以用两种不同的方式创建slice对象(类似于range函数创建range对象)。如果向slice函数传递一个参数,那么这将是终止位置。如果我们将三个参数传递给slice函数,那么它们将接受start、stop和step值。换句话说,start和step参数默认为None。

以下是使用slice对象的一些例子:

num_list[:8] is equivalent to num_list[slice(8)]num_list[2:8] is equivalent to num_list[slice(2,8,None)]num_list[2:] is equivalent to num_list[slice(2,None,None)]

如果我们想保存一个特定的切片对象并多次使用它,那么使用slice函数来创建一个切片对象是非常有用的。可以这样做,首先实例化一个slice对象并将其赋值给一个变量,然后在方括号内使用该变量。

evens = slice(None,None,2)num_list[evens]#[0,10,20,30,40]odds = slice(1,None,2)num_list[odds]#[5,15,25,35]
结论

在本教程中,我们首先回顾了使用方括号内的正或负索引来提取单个元素。然后比较了索引序列和切片序列,切片序列可以检索序列的一部分。我们学习了如何使用方括号和冒号对序列进行切片,包括指定要检索的部分的不同方法。

由于Python中的列表是可变的,我们看到了如何使用切片赋值来改变列表的某些部分。然后我们了解了切片列表和切片字符串之间的区别,切片列表返回列表的副本,而切片字符串返回对原始字符串对象的引用。最后,我们学习了在Python中slice对象是如何使用的。

标签: #python索引值 #python字符串的索引