list = ["a", "b", "c", "d"]
print(list[3]) # Number 3 is "d"
print(list[-4]) # Number -4 is "a"
list = ["a", "b", "c", "d"]
print(list[3]) # Number 3 is "d"
print(list[-4]) # Number -4 is "a"
换句话来说,因为-0
等于0
,如果从0
开始向后索引,会让解释器感到模棱两可。
如果你对-
感到困惑,想要另一种更易理解的方式向后索引,可以尝试使用~
,它是正向索引的镜像:
arr = ["a", "b", "c", "d"]
print(arr[~0]) # d
print(arr[~1]) # c
~
的典型用法是像“交换镜像节点”或“在排序列表中找到中位数”:
"""swap mirror node"""
def reverse(arr: List[int]) -> None:
for i in range(len(arr) // 2):
arr[i], arr[~i] = arr[~i], arr[i]
"""find median in a sort list"""
def median(arr: List[float]) -> float:
mid = len(arr) // 2
return (arr[mid] + arr[~mid]) / 2
"""deal with mirror pairs"""
# verify the number is strobogrammatic, strobogrammatic number looks the same when rotated 180 degrees
def is_strobogrammatic(num: str) -> bool:
return all(num[i] + num[~i] in '696 00 11 88' for i in range(len(num) // 2 + 1))
~
实际上是一种反码和补码的数学技巧,在某些情况下更容易理解。
关于是否应该使用像~
这样的Python技巧的讨论:
我认为,如果是自己维护的代码,可以使用任何技巧来避免潜在的错误或更轻松地实现目标,因为可能具有更高的可读性和可用性。但在团队合作中,避免使用“过于聪明”的代码,可能会给同事们带来麻烦。
例如,这里是Stefan Pochmann的一个简洁代码,用于解决这个问题。我从他的代码中学到了很多东西。但有些只是为了好玩,太过hackish难以使用。
# a strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at upside down)
# find all strobogrammatic numbers that are of length = n
def findStrobogrammatic(self, n):
nums = n % 2 * list('018') or ['']
while n > 1:
n -= 2
# n < 2 is so genius here
nums = [a + num + b for a, b in '00 11 88 69 96'.split()[n < 2:] for num in nums]
return nums
如果你感兴趣,我已经总结了类似这样的Python技巧。
n<2
。只需5行即可解决复杂问题。@Konrad - recnaclist[-1]
是“short hand”的简写形式:
list[len(list)-1]
len(list)
部分是隐含的。这就是为什么 -1
是最后一个元素。对于任何负数索引都适用——从 len(list)
减去的部分总是隐含的。
a
是列表还是列表的一个元素? - detly-0
等于0
。0
可以获取列表的第一个元素,-1
可以获取列表的最后一个元素。list = ["a", "b", "c", "d"]
print(list[0]) # "a"
print(list[-1]) # d
你也可以将其视为“list [len(list)-x]”的速记,其中x是从后面计算元素位置。仅当0 < -(- x)< len(list)时,此方法才有效。print(list[-1]) # d
print(list[len(list) - 1]) # d
print(list[-5]) # list index out of range
print(list[len(list) - 5]) # a
0
了。@Barmar - Koray Tugay这个习语可以使用模算法进行证明。我们可以将索引看作是指向列表中一个单元格的索引,该列表是通过向前步进 i
个元素而获得的。-1
指向列表的最后一个元素,是这种自然推广的一种形式,因为如果我们从列表开头向后走一步,就会到达列表的最后一个元素。
对于任何列表xs
和索引i
,无论是正数还是负数,表达式
xs[i]
将与下面的表达式具有相同的值或产生 IndexError
:
xs[i % len(xs)]
最后一个元素的索引是 -1 + len(xs)
,它与 len(xs)
取模等于 -1
。例如,在长度为 12 的数组中,最后一个元素的索引为 11,11 对于 12 取模等于 -1。
在 Python 中,数组更常用作 线性 数据结构而不是 环形 数据结构,所以索引大于 -1 + len(xs)
或小于 -len(xs)
都会越界,因为很少需要,并且如果数组的大小发生变化,效果会非常反直觉。
另一个解释:
你的手指指向第一个元素。索引决定了你将手指向右移动多少个位置。如果索引是负数,则将手指向左移动。
当然,你不能从第一个元素向左移动,所以向左的第一步会绕到最后一个元素。
steps= ["a", "b", "c", "d"]
a
开始走到 d
,a 是你的起点(或你的家),所以标记为 0(因为你还没有移动)。0
,因为你的家人住在那里,所以你的办公室不能是 0
。它是你的最后一个停留地点。last
指的是结束或最终,而不是最近的。@RaimundKrämer - AbstProcDo