简体   繁体   中英

Looping through triplets for zigzag pattern

I am trying to see if groups of three with consecutive elements have a zigzag pattern. Add to an empty list "1" for a zig, "1" for a zag, or "0" for neither. It seems to satisfy my first "if" condition and my "else" statement but never the middle. I've tried it as two if statement, one if and one elif, and nested. The answer should be [1,1,0] but I can only get [1,0] or no output and sometimes " index out of range". input [1,2,1,3,4] output [1,1,0]

    def solution(numbers):
        arr = []
        for i in range(len(numbers)-2):
            if numbers[i+1] > numbers[i] and numbers[i+2]:
                arr.append(1)
            if numbers[i+1] < numbers[i] and numbers[i+2]:
                arr.append(1)
            else:
                arr.append(0)
                return arr

Break the solution into two parts:

  1. Build a list of the differences between consecutive numbers (the zigs and zags).
  2. Return a list of the differences between consecutive zigs and zags (the zigzags).

You can use zip with slices to iterate over each pair of consecutive elements:

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]

You've got a sliding window here.

You're getting IndexError because your code has for i in range(len(numbers)) , and then you ask for numbers[i+2] . To prevent this, reduce the range:

for i in range(len(numbers) - 2):
    <do checks on numbers[i], numbers[i+1], numbers[i+2]>

But you may prefer to zip some slices together:

for a, b, c in zip(numbers[:-2], numbers[1:-1], numbers[2:]):
    <do checks on a, b, c>

You can use zip to combine elements 3 by 3 and compare each trio to check if the middle element is either greater than both its neighbours or smaller than both of them:

numbers = [1,2,1,3,4]

result = [int((a-b)*(b-c)<0) for a,b,c in zip(numbers,numbers[1:],numbers[2:])]

print(result) # [1, 1, 0]

zip will combine items offset by 0, 1 and 2 yielding the following trios:

numbers        [1,2,1,3,4]
numbers[1:]    [2,1,3,4]
numbers[2:]    [1,3,4] 
zip():          * * *   <-- 3 trios (extras are ignored)

 a,b,c   a-b    b-c      (a-b)*(b-c)   int(...<0)
------- 
(1,2,1)  -1      1          -1            1
(2,1,3)   1     -2          -2            1 
(1,3,4)  -2     -1           2            0 

Thanks everyone!

It was suggested I define my end range to avoid index out of range errors ( changed to len(numbers)-2) and that I change my formatting from "numbers[i+1] < numbers[i] and numbers[i+2]" to "numbers[i] > numbers[i+1] < numbers[i+2]". Also suggested I try the zip function which I will learn for next time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM