laboon
laboon

Reputation: 113

Check if a Python list has X number of consecutive values equal to Y

I have a collection of lists each containing 16 items, and I want to find lists with 12 consecutive values either > or < than a specified threshold. For now, I have iterated through the lists and put 1 for values greater and -1 for values less than the threshold, and I used to following to eliminate those that don't have 12 of either.

if list.count(-1) >= 12 or list.count(1) >= 12:

How do I efficiently check for 12 consecutive values? (12 values can loop around) for example this would count

[1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1]

Currently I have 2 nested for loops, but I know this checks the same value multiple times.

                    for i in range(16):
                        light = 0
                        dark = 0
                        for j in range(12):
                            index = i + j
                            if index > 15:
                                index -= 15
                            if list[index] == 1:
                                light += 1
                            elif list[index] == -1:
                                dark += 1
                            else:
                                break
                            if dark > 0 and light > 0:
                                break
                        if dark == 12 or light == 12:
                            return True

Upvotes: 0

Views: 1614

Answers (3)

BigBill
BigBill

Reputation: 40

You can loop through the list while keeping track how many times you've seen a specific value. Everytime you see a different value this counter resets (because you are looking for consecutive values).

def consective_values(input_list, target_value):
    i = 0
    count = 0
    for _ in range(2 * len(input_list)):
        if input_list[i] == target_value:
            count += 1
        else:
            count = 0
        if count == 12:
            return True
        i = (i + 1) % len(input_list)

    return False

Because the consecutive values can loop around you have to be a bit more careful with the list indexing and the loop variable. The max number of loops is equal to twice the length of the list. When you still haven't found 12 consecutive values at this point you know there aren't any. TO have an index loop around a list you can always apply the modulo (%) operator

Upvotes: 0

Ckrielle
Ckrielle

Reputation: 64

If I've understood correctly what you want, then here are some ways to do it:

First off you can sort the list, putting every element in an order, and then doing a linear search and incrementing a counter every time it's the same value with the previous list element

a.sort()
count = 0
for i in range(16):
    if count == 12:
        break
    if a[i - 1] == a[i]:
        count += 1

Another way to do it is with the modulo operator, which doesn't require you sorting the list. And you can add some variables to check if you've done a full loop.

flag_count = 0
count = 0
i = 0
while True:
    if count == 12 or flag_count == 2:
        break
    if a[i % 15] == a[(i + 1) % 15]:
        count += 1
    if i % 15 == 0:
        flag_count += 1
    i += 1

Upvotes: 0

Daweo
Daweo

Reputation: 36450

I would harness itertools.groupby following way

import itertools
data = [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1]
runs = [len(list(g)) for _,g in itertools.groupby(data)]
if data[0] == data[-1]:
    runs[0] += runs.pop()
print(max(runs) >= 12)  # True

Explanation: I use itertools.groupby to get length of runs (in this case [7,4,5]) - itertools.groupby does group only adjacent equal elements, then if first and last values of data are equal I extract last element from runs and add it to first element (as you allow wraparound), then I check if longest run is equal or greater 12.

Upvotes: 4

Related Questions