'Have a list of length n. How to iterate over it and only break if the last name number, else: append the index of the first index
Original List = [1,2,3,5,10,9,8,9,10,11,7,8,7]
Have a series of lists with RUN_LENGTH of 3 that I was able to splice using a Sliding window. After splicing I got these lists:
[1,2,3]
[2,3,5]
[3,5,10]
[5,10,9]
[10,9,8]
[9,8,9]
[8,9,10]
[9,10,11]
[10,11,7]
[11,7,8]
[7,8,7]
I am trying to iterate over each of these lists one by one. While doing so I am comparing whether the last number in that list was either 1 greater or less (+-1) than the previous number. If it's not, we want to break that loop and check the next sub-list [2,3,5]. If it is, we want to continue and check every number from n[0] to n[RUN_LENGTH] to make sure they are in sequence (+-1). After the last number has been checked and the conditions are not broken (All numbers were sequential to each other); we want to save the first index number from that sub-list (about the Original_List, so I from Original_List[i]) and append it to a (blank) index we have set-up.
So for example:
[1,2,3] = Success
[10,9,8] = Success
[9,8,9] = Fail
[11,7,8] = Fail
[8,9,10] = Success
The expected result, in this case, would be:
indicies = [0,4,6,7]
Below is my code. For some reason I can't figure out how to properly iterate through each of those lists to check whether x(i) = x(i-1) +- 1:
Original_List = [1,2,3,5,10,9,8,9,10,11,7,8,7]
index1 = []
RUN_LENGTH = 3
for i in range(len(Original_List) - RUN_LENGTH):
i1 = i #set pointers for later
i2 = i #
triplet = Original_List[i:i+RUN_LENGTH]
for i, x in enumerate(triplet):
i2 = i
if i2 - i1 != 1 and i1 - i2 != 1: #compare whether the last number is within +-1 of the last number. If not, break and check next triplet.
break
else:
i1 = x #assign current list value to i1 so we can assign next value to i2
continue
#if on last number of the triplet and everything is still in sequence (loop didnt break), append number (so [1,2,3] [6,5,4] but not [4,5,4]
index1.append(i)
print('indicies = ' + str(index1))
Solution 1:[1]
Ok, we're looking for all length n runs that either keep stepping up by one or down by one.
We can look at the current window pairwise, map difference over those pairs, then check that all the differences are the same and either -1 or +1.
from operator import sub
from itertools import pairwise, starmap
def indices_of_length_n_runs(l, n):
indices = []
desired_diffs = {1, -1}
if len(l) < n:
raise ValueError(f"List {l} is shorter than run length {n}")
for index in range(len(l)-n):
diffs = set(starmap(sub, pairwise(l[index:index+n])))
if len(diffs) == 1 and desired_diffs.intersection(diffs):
indices.append(index)
return indices
indices_of_length_n_runs([1,2,3,5,10,9,8,9,10,11,7,8,7], 3)
# [0, 4, 6, 7]
paiwise was added to itertools in version 3.10, but you can find a simple recipe for it in the documentation that you can use on older versions.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Patrick Haugh |
