切片跨越字符串边界?

Slices cross strings boundaries?

提问人:Vladimir Zolotykh 提问时间:4/2/2018 最后编辑:Vadim KotovVladimir Zolotykh 更新时间:4/2/2018 访问量:67

问:

请详细解释:

>>> [line.rstrip() for line in open('foo')]
[',' 'hello text file6', '', '', '', 'goodby text file7', '', 'bye', '']

>>> with open('foo') as f: [line.rstrip() for line in f if line.rstrip()[-1:].isdigit()]
... 
['hello text file6', 'goodby text file7']

[-1:] 忽略空字符串,而上面的列表推导式有空字符串。到目前为止,我习惯于切片只在一个字符串中工作。[-1:] 切片似乎跨越了许多字符串的边界。

字符串 python-2.7 列表推导 切片

评论

0赞 Norrius 4/2/2018
您打印了其中的行是非空的,并且 .这里有什么出乎意料的?lineline[-1].isdigit()
0赞 Vladimir Zolotykh 4/2/2018
line[-1] 给出空字符串的错误“IndexError:字符串索引超出范围”
0赞 Norrius 4/2/2018
这是因为切片不是索引,工作方式略有不同。具体而言,越界切片是一个空序列。这是你的问题吗?
0赞 Vladimir Zolotykh 4/2/2018
我还是不太明白。我们将 slice 应用于单个字符串。某处一定是应用切片的字符串的隐式串联,而不是原始的空“”字符串。这很复杂,或者我可能错过了一些重要的东西。
0赞 Vladimir Zolotykh 4/2/2018
此处的切片只是不出现“超出范围”错误的解决方法

答:

1赞 cwallenpoole 4/2/2018 #1

分解内容:

  • 切片(语法)将处理该范围内的所有可能值。这意味着所有这些都是正确的。[::]

    • ['cat'][0:1] == ['cat']
    • ['cat'][1:2] == []
    • ['cat'][-1:2] == ['cat']
    • ['cat'][-10000:] == ['cat']
  • 另一方面,通过索引访问某些内容 ( 如果索引不存在,则将失败。这意味着这些失败:[x]

    • ['cat'][1]
    • ['cat'][-2]
  • 你的理解意味着“采取所有满足以下条件的:line

    • 如果你是他们,它们不是空的(记住空字符串不是数字)rstrip
    • 表示最后一个字符的子字符串是数字

您可能需要以下内容:

 [line.rstrip() for line in f if not line.rstrip() or line.rstrip()[-1].isdigit()]

这将包括您的空行。


需要说明的是,您绝不会从字符串外部获取值。 (无冒号)将失败。''[-123:]''[-123]

评论

0赞 Vladimir Zolotykh 4/2/2018
没有跨越没有字符串边界)只是得到空字符串''而不是'超出范围错误' >>> '6'[-1:] '6' >>> ''[-1:] ''
0赞 cwallenpoole 4/2/2018
@VladimirZolotykh没错。 表示“获取范围内的所有值”,而表示“获取索引 -1 处的值”。[-1:][-1]
1赞 Norrius 4/2/2018 #2

没有隐式串联,切片不这样做。请看这个例子:

lines = ['', 'abc', 'xyz123']

for line in lines:
    print repr(line.rstrip()[-1:]),
    print line.rstrip()[-1:].isdigit()

输出:

'' False
'c' False
'3' True

意想不到的部分可能是它如何处理空字符串。空字符串的任何切片都将是空字符串,因为越界切片是空序列。然后,将 str.isdigit 定义为在空字符串上返回 False,因此这些字符串将从列表中筛选出来。

评论

0赞 Vladimir Zolotykh 4/2/2018
切片不如索引严格(返回空字符串而不是引发错误),空字符串由我的理解过滤。你的“空字符串的任何切片都将是空字符串,因为越界切片是一个空序列”更切中要害。