在for循环中倒序索引整个数组

5
假设我想循环遍历一个数组,并在循环中正向和反向索引该数组的所有索引,如下所示:
x = np.random.uniform(size=600)
for i in range(len(x)):
    dot = np.dot(x[:-i], x[i:])

现在这不起作用,因为x[:-0]就像x[:0]一样,会得到[]。 我可以分别处理零的情况,但想知道是否有更Pythonic的方法。

2个回答

9
使用切片时,将结束位置的值设为-i或None。如果i不为零,则它就是-i;但如果它是0,那么-0为假值,它将评估和返回第二个术语None,表示“运行到序列结尾”。这能够奏效是因为foo[:None]等同于foo[:],当省略切片组件时,它会隐式地变成None,但显式传递None也是完全合法的,具有相同的效果。

所以你的新代码行应该是:

dot = np.dot(x[:-i or None], x[i:])

5
它与"truthy"很搭配。 :-) 我更喜欢使用它而不是"true"和"false",因为在Python中,你很少关心实际值 TrueFalse,你只关心一个值是否为真或假以进行布尔值评估;truthy或falsy清楚地表明你关心的是含义,而不是具体值。 - ShadowRanger
我看到你之前玩过刀叉游戏了 https://www.youtube.com/watch?v=mcE0aAhbVFc - FuriousGeorge
整洁。我可能会选择[:len(x) - i],但这只是因为我对非布尔值的布尔计算的依赖感到不安。 - Rune Lyngsoe
@RuneLyngsoe:是的,那也可以,但速度会更慢(特别是如果你没有在循环外面预先计算len(x)并将其存储下来;调用内置函数的开销非常高,尽管它们实际上做的工作很少)。-i或None仅在常见情况下增加了一个隐式布尔运算(除了pass语句之外,这是CPython可以做的最便宜的事情),而len(x) - i则对每个使用都添加了内置查找、内置调用和减法操作(如果你预先缓存,则本地加载和减法成本至少会多花费一点点)。 - ShadowRanger

2
为什么不直接使用长度信息:
length = len(x)

for i in range(length):
    dot = np.dot(x[:length-i], x[i:])

我认为他们想要比x的长度更小的一部分。 - AncientSwordRage
@Pureferret 它比x的长度小(除了第一次迭代)。 - miindlek
是的,这与ShadowRanger的解决方案等效,谢谢! - lhcgeneva

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接