字符实战——索引和切片——高级切片——第三个(索引)限制(参数)和切片对象
在 Python2.3 和之后版本中,切片表达式支持可选的第三索引参数(用作步长(有时被称为 stride))。这个步长被添加到提取出的每项的索引上。
切片的完整形式现在是 X[I:J:K]
,它意味着” 提取在 X 中的从偏移量 I 到 J-1,步长为 K 的所有项 “。第三个限制(参数)K 默认为 +1
,它通常是切片中的所有项从左到右被提取出来的原因。然而,如果指定一个具体值,就可以使用第三限制(参数)来跳过项或逆转顺序。
比如,X[1:10:2]
将从偏移量 1 到 9,每隔一个提取 X 中的项;也就是说,它将提取在偏移量 1,3,5,7,9 的项。同平时一样,第一,二限制(参数)分别默认为 0 和序列的长度,所以 X[::2]
从开始到结束,每隔一个提取 X 中的项:
>>> S = 'abcdefghijklmnop'
>>> S[1:10:2] # 跳过项
'bdfhj'
>>> S[::2]
'acegikmo'
还可以使用负步长来反向提取项。比如,切片表达式 "hello"[::-1]
返回了新字符串 "olleh"—— 和以前一样,前两个边界默认为 0 和序列长度,-1 的步长表明这个切片应该从右往左而非通常的从左往右。因此,效果就是逆转序列:
>>> S = 'hello'
>>> S[::−1] # 逆转项
'olleh'
使用负步长,前两个边界的含义本质上就被反转了。也就是说,切片 S[5:1:-1]
是以相反的顺序,从 2 到 5 获取项(结果包含从偏移量 5,4,3,2 的项):
>>> S = 'abcedfg'
>>> S[5:1:−1] # 边界作用不同了。
'fdec'
像这样的跳过和反转是第三限制参数切片的最常见用例,但要获取更多细节请参见 Python 标准库手册(或交互地运行一些实验)。本书稍后将和 for
循环语句一起,重温第三限制参数切片。
本书稍后还会学到切片操作等价于带有一个切片对象的索引操作,对寻求同时支持这两个操作的类的作者,这是一个重大发现:
>>> 'spam'[1:3] # 切片操作语法
'pa'
>>> 'spam'[slice(1, 3)] # 切片对象带有索引语法和索引对象
'pa'
>>> 'spam'[::-1]
'maps'
>>> 'spam'[slice(None, None, −1)]
'maps'
为什么会关心:切片#
在整本书中,我将包括一些常见的用例侧边栏(比如这个)来让你了解正在被介绍的语言特性在真实程序中通常是如何被使用的。因为在对 Python 有更好的整体理解前,将不会十分理解实际用例,这些侧边栏不可避免地包含许多还未介绍的主题的引用;最多应该将它们认为是发现这些抽象语言概念对日常编程任务有用的方法的预览。
比如,稍后将看到:用于启动 Python 程序的系统命令行上列出的参数单词,在内置的 sys
模块的 argv
属性中可用:
# File echo.py
import sys
print(sys.argv)
% python echo.py −a −b −c
['echo.py', '−a', '−b', '−c']
通常,只有兴趣去检查跟在程序名称后的参数。这导致切片的一个典型应用:一个切片表达式可用来返回列表中除了第一项的所有项。这里,sys.argv[1:]
返回想要的列表:['-a', '-b', '-c']。然后可以处理这个列表而无需适应在前面的程序名。
切片还常用来清理从输入文件读取的行。如果知道行在末尾将有一个行尾字符(一个 \n
换行标记),可以使用单个表达式如 line[:-1]
(它提取了行中除了最后一个字符的所有字符 —— 下限默认为 0)来去除它。在这两种情况下,切片都完成了在底层语言中必须明确写清楚的逻辑工作。
话虽如此,调用 line.rstrip
方法通常更适合来去除换行符,因为如果在行尾没有换行符(使用一些文本编辑工具创建文件的一个常见情况),这个调用会让该行保持完整。如果确定行被合适地终止,则切片方法可以正常工作。
” 切片都完成了在底层语言中必须显式的逻辑工作。“#
下面是在 C 语言中读取输入文件的行然后移除行尾的换行符的例子:
int main(void) {
char line[MAX_LINE_LENGTH];
// Open input file
FILE *fp = fopen("input.txt", "r");
if (fp == NULL) {
perror("Failed to open file");
exit(EXIT_FAILURE);
}
// Read line from input file
fgets(line, MAX_LINE_LENGTH, fp);
// Remove newline character from line
int i;
for (i = 0; line[i] != '\0'; i++) {
if (line[i] == '\n') {
line[i] = '\0';
break;
}
}
// Print the line without newline character
printf("Line: %s\n", line);
// Close input file
fclose(fp);
return 0;
}
而在 Python 中,同样的功能,代码如下:
with open('input.txt', 'r') as f:
line = f.readline()[:-1]
print('Line:', line)
可以看到,在 Python 中只需要简单地使用 slice 就可以达到目的,而在 C 中却必须循环字符串中的字符并明确地检查是否为换行符来移除它。
推荐文章: