我阅读了有关Python字符串切片(Reverse string: string[::-1] works, but string[0::-1] and others don't)的帖子,但是仍然有一些疑问。哪个优先?它是开始/结束位置的一个或多个索引吗?还是一步?首先评估哪个?
我在Python中尝试了很少的东西,结果却不一致。参见下面的代码/示例。我已经将自己的分析放在方括号中,这可能是错误的,因此也请帮助我进行更正。
txt="abcdef"
txt[::-1]
结果='fedcba'
(此处优先选择该步骤,因为它为负数,所以它从最后一个索引(即5或-1)开始,一直持续到第一个字符'a')
txt[0:0:-1]
结果=''
(似乎索引首先被评估。因此从0开始但在0之前结束,这是不可能的,因此没有结果。甚至没有评估步骤。)
txt[:0:-1]
结果='fedcb'
(优先选择步骤,然后再考虑索引。因此,第一个索引变为纬度位置“ f”,直到到达“ a”之前的一个位置)
txt[0::-1]
结果='a'
(对此我感到很惊讶。这里似乎优先选择了起始索引。首先将索引0评估为'a',然后评估步骤'-1'。但是由于步骤'-而无法访问其他内容1',则不再打印任何字符)
5a。 txt[0:1]
result ='a'(为什么?step的默认值为'1'。似乎首先评估起始索引,访问'a',打印然后停止)。
5b。 txt[0:1:1]
结果='a'(与5a相同)
5c。 txt[0:1:-1]
结果=”(为什么呢?将其与5a进行比较。似乎在5c中,首先对step求值,然后对起始索引进行评估。如果应该先对起始索引求值,则应至少打印出“ a”)。
txt[0:-1:-1]
结果=”(我期望基于对起始索引的偏好而获得'a')
txt[0::-1]
result ='a'(现在将其与上面的示例6进行比较。为什么这次会有不同的结果?空白的结束索引等效于直到到达字符串的末尾,不是吗?)
txt[:len(txt):-1]
result =''(将其与6和7进行比较)
txt[:0:-1]
结果='fedcb'(似乎优先考虑步骤,然后对表达式进行求值。基于步骤-1,将起始索引求值为最后一个位置'f')
所有这些至少让我感到困惑。
答案 0 :(得分:3)
用于插槽的默认数字值(无论它们是空白还是None
)都是
len(x)-1
len(x)
,如果步数为负,则为-len(x)-1
向后移动时,末尾插槽的一个奇怪的默认设置是取消添加len(x)
作为负索引。
如果未指定步骤,则它的“优先级”仅在于其默认设置会影响其他两个步骤的默认设置。
提供所有值后,将切片定义为通过从起始值开始并在达到或超过终止值时停止(通过步骤的符号定义的“过去”)获得的许多元素(可能为0)
答案 1 :(得分:1)
from dis import dis
dis("txt[::-1]")
给我们
1 0 LOAD_NAME 0 (txt)
2 LOAD_CONST 0 (None)
4 LOAD_CONST 0 (None)
6 LOAD_CONST 2 (-1)
8 BUILD_SLICE 3
10 BINARY_SUBSCR
12 RETURN_VALUE
因此我们可以看到开始和结束的默认值实际上是None
。这意味着它们是在内部计算的,规则可能很复杂。但是,不是...
考虑以下(非常简单)的实现:
def impl(txt: str, start: int = None, end: int = None, step: int = 1):
print("txt[{}:{}:{}] = ".format("" if start is None else start, "" if end is None else end, step), end="")
# Handle the default values:
if start is None:
start = 0 if step >= 0 else len(txt) - 1
elif start < 0:
start = len(txt) + start
if end is None:
end = len(txt) if step >= 0 else -1
elif end < 0:
end = len(txt) + end
def compare(index, end, step) -> bool:
if step >= 0:
return index < end
if step < 0:
return index > end
# Compute the result
result = ""
index = start
while compare(index, end, step):
result += txt[index]
index += step
print(result)
return result
将在所有情况下通过:
txt = "abcdef"
# 1.
assert (txt[::-1] == "fedcba" == impl(txt, None, None, -1))
# 2.
assert (txt[0:0:-1] == "" == impl(txt, 0, 0, -1))
# 3.
assert (txt[:0:-1] == "fedcb" == impl(txt, None, 0, -1))
# 4.
assert (txt[0::-1] == "a" == impl(txt, 0, None, -1))
# 5a
assert (txt[0:1] == "a" == impl(txt, 0, 1))
# 5b
assert (txt[0:1:1] == "a" == impl(txt, 0, 1, 1))
# 5c
assert (txt[0:1:-1] == "" == impl(txt, 0, 1, -1))
# 6.
assert (txt[0:-1:-1] == "" == impl(txt, 0, -1, -1))
# 7.
assert (txt[0::-1] == "a" == impl(txt, 0, None, -1))
# 8.
assert (txt[:len(txt):-1] == "" == impl(txt, None, len(txt), -1))
# 9.
assert (txt[:0:-1] == "fedcb" == impl(txt, None, 0, -1))
# Some others
assert (txt[::2] == "ace" == impl(txt, None, None, 2))
assert (txt[::-2] == "fdb" == impl(txt, None, None, -2))
assert (txt[:-1:-2] == "" == impl(txt, None, -1, -2))
assert (txt[-2::-2] == "eca" == impl(txt, -2, None, -2))