Home > Software design >  Counting how many times value meets 2 times in a row in list
Counting how many times value meets 2 times in a row in list

Time:04-23

I need to count how many times 'Eagle' appears 2 times in a row in random generated list. In case ['Eagle', 'Eagle', 'Eagle', 'Eagle'] it should count 2, not 3

import random
def HeadsOrTails(amo):
amo1 = []
Coin = ['Eagle', 'Tails']
for i in range(amo):
    amo1.append(random.choice(Coin))
return amo1

count = 0

for i in range(len(HeadsOrTails(30))):
    if HeadsOrTails(30)[i] == 'Eagle':
        if HeadsOrTails(30)[i] == HeadsOrTails(30)[i 1]:
            count  = 1
    else:
        continue

print(HeadsOrTails(30))
print(f' Eagle repeats {count} times in the list')

For some reason it calculates amount of values wrongly

CodePudding user response:

Use a while loop and increment the indexer upon a match:

def count2(l):
    i = 1
    count = 0
    while i < len(l):
        if l[i] == l[i-1] == 'Eagle': # if both values are "Eagle"
            count  = 1  # increment the counter
            i  = 1      # and skip a step (with below, equivalent to i  = 2)
        i  = 1          # increment to next step
    return count

Examples:

count2(['Eagle', 'Eagle', 'Eagle', 'Eagle'])
# 2

count2(['Eagle', 'Eagle', 'Eagle'])
# 1

count2(['Eagle', 'Eagle', 'Tails', 'Eagle'])
# 1

count2(['Eagle', 'Eagle'])
# 1

count2(['Eagle'])
# 0

count2([])
# 0
generalization (counting n successive values)

you can use slicing and comparison to a set:

def countn(l, n=2, match='Eagle'):
    i = n-1        # start at n-1 position
    count = 0
    while i < len(l):
        if set(l[i-n 1:i 1]) == {match}: # if all values of the slice are "match" (= consecutive match)
            count  = 1    # increment counter
            i  = n        # and skip n steps
        else:
            i  = 1        # else, go to the next step
    return count

example:

countn(['Eagle', 'Eagle', 'Eagle', 'Eagle', 'Eagle', 'Eagle'], n=3)
# 2

countn(['Eagle', 'Eagle', 'Eagle', 'Eagle', 'Eagle'], n=3)
# 1

countn(['Eagle', 'Eagle', 'Eagle'], n=3)
# 1

countn(['Eagle', 'Eagle', 'Tails', 'Eagle'], n=3)
# 0

countn([], n=3)
# 0

CodePudding user response:

You should generate the list only once.
If 2 adjacent items are both Eagle then you skip to 2 items, else you skip only one.

list_size = 30
my_list = heads_or_tails(list_size)
count = 0

i = 0
while i < list_size  -1:
    if my_list[i] == my_list[i 1] == 'Eagle':
        count  =1
        i  =2
    else:
        i  =1
print(count)

CodePudding user response:

Once you've built the list of Heads and Tails you should iterate over it comparing the current element with the element one index position ahead. If they're the same (HEAD) then advance the index by 2 otherwise increment by 1.

Therefore:

import random

HEAD = 'Eagle'
TAIL = 'Tail'
PAIR = [HEAD, HEAD]
N = 30

def HeadsOrTails(n):
    return random.choices([HEAD, TAIL], k=n)

coins = HeadsOrTails(N)

i, c = 0, 0

while i < len(coins) - 1:
    if coins[i:i 2] == PAIR:
        c  = 1
        i  = 2
    else:
        i  = 1

print(coins)
print(c)

CodePudding user response:

When you do this HeadsOrTails(30), each time it will compute a new one. Then in order to do what you expect, call it once and store its result in a variable.

And your code doesn’t control the fact that we are in a group of more than 3. I added this.

import random


def heads_or_tails(amo):
    amo1 = []
    coin = ["Eagle", "Tails"]
    for i in range(amo):
        amo1.append(random.choice(coin))
    return amo1


my_head_or_tails = heads_or_tails(30)

count = 0
already_in_pair = False
for i in range(len(my_head_or_tails)):
    current_is_eagle = my_head_or_tails[i] == "Eagle"
    try:
        next_is_eagle = my_head_or_tails[i   1] == "Eagle"
    except IndexError:
        next_is_eagle = False

    if current_is_eagle and next_is_eagle and not already_in_pair:
        count  = 1
        already_in_pair = True
    else:
        already_in_pair = False


print(my_head_or_tails)
print(f" Eagle repeats {count} times in the list")

CodePudding user response:

Yet another approach. Build a list of positions and then check if the position(s) are present within the list. Instead of a count we return the pos_list and print the length of that list.

import random


def heads_or_tails(amo):
    amo1 = []
    coin = ['Eagle', 'Tails']
    for i in range(amo):
        amo1.append(random.choice(coin))
    return amo1


def get_count(searchstr='Eagle'):
    pos = []
    _lst = heads_or_tails(10)
    for j in range(len(_lst)):
        try:
            if _lst[j] == searchstr and _lst[j 1] == searchstr:
                if j not in pos and j-1 not in pos:
                    pos.append(j)
            else:
                continue
        except IndexError:
            pass
    return _lst, pos, searchstr


search_list, pos_lst, search_str = get_count()
print(search_list)
print(f'{search_str} repeats {len(pos_lst)} times in the list')

CodePudding user response:

import numpy as np

lst = list(np.random.choice(['Eagle', 'Tails'], size=10))
print(lst)

count = 0
pt = ''
while len(lst):
    item = lst.pop(0)
    if pt == item and pt == 'Eagle':
        pt = ''
        count  = 1
    else:
        pt = item
print(count)
  • Related