'Counting how many times value meets 2 times in a row in list
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
Solution 1:[1]
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
Solution 2:[2]
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)
Solution 3:[3]
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)
Solution 4:[4]
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")
Solution 5:[5]
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')
Solution 6:[6]
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)
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 | |
| Solution 2 | TDG |
| Solution 3 | Albert Winestein |
| Solution 4 | |
| Solution 5 | Dan Green |
| Solution 6 | Kang San Lee |
