将解决方案分为两部分:
- 建立一个连续数字(之字形和锯齿形)之间差异的列表。
- 返回连续之字形和之字形(之字形)之间的差异列表。
您可以使用zip
with slices 来遍历每对连续元素:
def zig_zags(numbers):
zigzags = [(a - b) // abs(a - b) for a, b in zip(numbers, numbers[1:])]
return [int(a and b and a != b) for a, b in zip(zigzags, zigzags[1:])]
print(zig_zags([1, 2, 1, 3, 4])) # [1, 1, 0]
为了进一步分解,让我们使用 REPL 来看看zip
slice 是如何工作的:
>>> numbers = [1, 2, 1, 3, 4]
>>> numbers[1:]
[2, 1, 3, 4]
>>> [(a, b) for a, b in zip(numbers, numbers[1:])]
[(1, 2), (2, 1), (1, 3), (3, 4)]
切片[1:]
从第二个元素开始获取列表,并zip
获取两个列表(原始列表和偏移一的切片版本)并一次从每个列表中产生一个元素——所以总的来说,我们得到了连续的对元素。
现在让我们采用相同的表达式,但要减去 a
而b
不是将它们变成元组:
>>> [a - b for a, b in zip(numbers, numbers[1:])]
[-1, 1, -2, -1]
负数显示原始列表在哪里减少(锯齿形),正数显示它在哪里增加(锯齿形)。(如果它既不是曲折也不是曲折,那就是零。)如果我们对曲折和曲折进行归一化,比较曲折和曲折会更容易:
>>> [(a - b) // abs(a - b) for a, b in zip(numbers, numbers[1:])]
[-1, 1, -1, -1]
现在每个“zig”都是-1,每个“zag”都是+1。所以现在让我们看看之字形跟随之字形的位置:
>>> zigzags = [(a - b) // abs(a - b) for a, b in zip(numbers, numbers[1:])]
>>> [(a, b) for a, b in zip(zigzags, zigzags[1:])]
[(-1, 1), (1, -1), (-1, -1)]
>>> [a != b for a, b in zip(zigzags, zigzags[1:])]
[True, True, False]
与之前完全相同的技术zip
,[1:]
但现在我们正在查看我们在第一步中计算的锯齿形和锯齿形。因为我们对它们进行了标准化,所以我们需要做的就是查看它们是否彼此相等。
我们还应该明确排除没有 zig或zag 的情况,即a
orb
为零的情况。看起来像:
>>> [a and b and a != b for a, b in zip(zigzags, zigzags[1:])]
[True, True, False]
最后,由于我们希望我们的输出是1
and0
而不是True
and False
,我们需要转换它。方便True
的是,当您转换为时,int
它会变为1
并False
变为0
,因此我们可以将整个内容包装在 中int
:
>>> [int(a and b and a != b) for a, b in zip(zigzags, zigzags[1:])]
[1, 1, 0]