Do only the first and the last true condition, - python

I have a live process the could be true or false in input. Based on the condition status, if it's true start to write the timecode in a file. I need to write the timecode just the first time the condition is true and add the number of times the condition was true.
So, if the statement is true 5 times, I need to write the timecode the first time the condition it's true, ignoring the next true condition, but counting them and write the times the condition was true in the file.
if process:
writeTC(fName,
TC_in, # write only the first time the condition is true
)
writeDuration(fName,
Duration # write duration only at the last true cond.
)
))
Output:
00:00:03:05
7 sec.
Old vague question.
Before answering, please read my question. I now how to use counter, what I'm asking is about the if statement. Thanks. I have a condition inside a loop. I want to print the result once, the first time the condition is true and add the number of times the condition was true.
arr = ['a', 1, 1, 1, 1, 1, 2, 2, 2, 2, 'a', 'a',
3, 3, 'a', 4]
for i in arr:
if type(i) == int:
print('Printed once {i}'.format(i=i))
I would like end up with this result:
There is 5 times the number 1
There is 4 times the number 2
There is 2 times the number 3
There is 1 times the number 4

This will work.I think Counter is the best function to count occurences in a list.
from collections import Counter
arr = ['a', 1, 1, 1, 1, 1, 2, 2, 2, 2, 'a', 'a',
3, 3, 'a', 4]
filteredArr = [x for x in arr if type(x)==int]
k = dict(Counter(filteredArr))
for i in k.keys():
print('There is {} the number {}'.format(k[i],i))

you can use Counter --
from collections import Counter
arr = ['a', 1, 1, 1, 1, 1, 2, 2, 2, 2, 'a', 'a',
3, 3, 'a', 4]
freq_dict = Counter([item for item in arr if type(x)==int])
for key,value in freq_dict.items():
print(f'There is {value} the number {key}')
Output -
There is 5 the number 1
There is 4 the number 2
There is 2 the number 3
There is 1 the number 4

I'm still not sure when you want to do the print statement, but may be a dictionary could be closer to what you want:
import time
arr = ['a', 1, 1, 1, 1, 1, 2, 2, 2, 2, 'a', 'a', 3, 3, 'a', 4]
numbers = {}
# extract all integers from the starting list
for element in arr:
if type(element) == int:
if element not in numbers.keys():
numbers.update({element: [time.time_ns(), 1]})
else:
numbers[element][1] += 1
for key in numbers.keys():
print(f"the number {key} occurs {numbers[key][1]} times. First occurrence at {numbers[key][0]} ")
First time an interger is found, it is written to the dictionary as key. The corresponding value takes the actual time and a counter.
Next time this integer is found, only the counter is increased.
So If you need the print statement while looping, just add it into the innerif else clause.

Related

how to gete sum of duplicate in list in python?

how do i check how what is the duplicate numbers and what their sum?
I am working on a project and I cant get it.
list = [1, 3, 5, 2, 1, 6, 5, 10, 1]
You can iterate the list and count how many times each element is met, then it's easy to check which elements are repeated (they have counter greater than 1), and the sum would be simply element_value*count
li = [1, 3, 5, 2, 1, 6, 5, 10, 1]
counters = {}
for element in li:
counters[element] = counters.get(element, 0) + 1
for element, count in counters.items():
if count >= 2:
print('Repeated element', element, 'sum=', element*count)
You can set up a separate set to check which items have already been seen, and for those where this is the case you add them to a sum:
sum = 0
li = [1, 3, 5, 2, 1, 6, 5, 10, 1]
seen_numbers = set()
for n in li:
if n not in seen_numbers:
seen_numbers.add(n)
else:
sum += n
Note that this will add a number that is already in the list each time it recurs, i.e., a number that appears three times will be added to sum twice. I don't know if that's what you want.
If you need the single results you can construct a list where each element is a tuple. Each tuple contains the number, the count and the sum.
from collections import Counter
data = [1, 3, 5, 2, 1, 6, 5, 10, 1]
result = [(value, count, value*count) for value, count in Counter(data).items() if count > 1]
print(result)
If you need to find only the full total of all values that appear more than once:
print(sum(value*count for value, count in Counter(data).items() if count > 1))

Adding condition in list in python

I don't know how to add extra conditions to this code.
(Only using randint)
For example with list [1, 2, 3, 4, 0] I need to generate random number except the last one (covered in my code) but the next condition is, it can not choose an index number which has a value of 0. So for list [3, 3, 0, 3, 3, 7] it can only consider indexes 0,1,3,4 (not 2 and 5 because I can not include the last number and index with value 0).
My code so far:
import random
our = [2, 3, 4, 0]
random_index = random.randint(0, len(our)-2)
random_number = our[random_index]
print(random_number)
I will be very glad for any help.
You can create a second list that stores the valid index values.
import random
our = [3, 3, 0, 3, 3, 7]
index = []
for i in range(0, len(our)-1) :
if our[i] != 0 :
index.append(i)
# index: [0, 1, 3, 4]
random_index = random.choice(index)
EDIT: You can perform a sanity check for a non-zero value being present.
The any() function returns True if any element of an iterable is True. 0 is treated as False and all non-zero numbers are True.
valid_index = any(our[:-1])
if valid_index:
index = []
for i in range(0, len(our)-1) :
if our[i] != 0 :
index.append(i)
You can use a while loop to check if the number equals 0 or not.
import random
our = [3, 6, 2, 0, 3, 0, 5]
random_number = 0
while random_number == 0:
random_index = random.randint(0, len(our)-2)
random_number = our[random_index]
print(random_number)

Why does python return index 0 if the item is 0 for the .index method?

[ss]https://i.imgur.com/dyggsaJ.png
howdy guys,
I wrote a list
l = [0, 0, 0, 1]
and asked Python to print the index for every item, like this
for i in l:
print(l.index(i))
It returns
0
0
0
3
Notice how it returns 0 for all the elements that are 0 but returns the correct index when the item is 1.
Similarly,
l2 = [0, 0, 3, 2, 5]
for i in l2:
print(l2.index(i))
# returns 0, 0, 2, 3, 4
l3 = [2, 3, 4, 0, 0]
for i in l3:
print(l3.index(i))
# returns 0, 1, 2, 3, 3. what?
But
l4 = [1, 2, 0, 3, 4]
for i in l4:
print(l4.index(i))
# returns 0, 1, 2, 3, 4
It seems that the loop goes wacky as soon as there are two elements in a row that are 0. Is there a name for this or an explanation? Did I write the code wrong?
You've got it wrong. If you try:
l = [2, 2, 2, 1]
for i in l:
print(l.index(i))
you will also get:
0
0
0
3
That is because during the ierations, you tell python to print the index of 0 three times. Python will only print the first index it sees that equal to what was specified.
As seen in the documentation,
list.index(x[, start[, end]])
returns "zero-based index in the list of the first item whose value is equal to x".
So, if there are two or more elements with the same value in your list, you will get always the index of the first occurence. In other words your code works as expected.
If you want the index and item of a list while iterating over each entry you can try either of the below 2 options -
Option 1:
for i in range(len(l)):
print(i)
Option 2:
for i,v in enumerate(l):
print(i)
Both the above options will give you the result 0 1 2 3

Retrieve the first element from Counter in O(n) time

I have such a nums list
In [72]: nums
Out[72]: [4, 1, 2, 1, 2]
try to get the unique number from the list
n [72]: nums
Out[72]: [4, 1, 2, 1, 2]
In [73]: c = Counter(nums)
In [74]: c
Out[74]: Counter({4: 1, 1: 2, 2: 2})
I can see the result from the counter, it is 4:1, but cannot retrieve it in O(1) time
In [79]: list(c)[0]
Out[79]: 4 #O(n) time
Is it possible to get 4 in O(1)time
According to the comments to the question, you want to get the elements that have a count of 1. But it is still not clear what you want to get exactly, as the term "the first element" is unclear in the context of a Counter, which is a dict and no defined order internally.
Here are a few options (I used str instead of int to make it clearer which are the values and which are their counts):
>>> import collections
>>> input_str = 'awlkjelqkdjlakd'
>>> c = collections.Counter(input_str)
>>> c
Counter({'l': 3, 'k': 3, 'a': 2, 'j': 2, 'd': 2, 'w': 1, 'e': 1, 'q': 1})
Get all elements that have count of 1 (takes O(k), where k is the number of different elements):
>>> [char for char, count in c.items() if count == 1]
['w', 'e', 'q']
Get one (random, not specified) element that has count of 1 (takes O(k), because the list has to be built):
>>> [char for char, count in c.items() if count == 1][0]
'w'
This can be improved by using a generator, so the full list will not be built; the generator will stop when the first element with count 1 is found, but there is no way to know if that will be first or last or in the middle ...
>>> g = (char for char, count in c.items() if count == 1)
>>> g
<generator object <genexpr> at 0x7fd520e82f68>
>>> next(g)
'w'
>>> next(char for char, count in c.items() if count == 1)
'w'
Now, if you want to find the count of the first element of your input data (in my example input_str), that is done in O(1) because it is a list item access and then a dict lookup:
>>> elem = input_str[0]
>>> elem
'a'
>>> c[elem]
2
But I cannot give a more concrete answer without more information on what exactly you need.

How do you calculate the greatest number of repetitions in a list?

If I have a list in Python like
[1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1]
How do I calculate the greatest number of repeats for any element? In this case 2 is repeated a maximum of 4 times and 1 is repeated a maximum of 3 times.
Is there a way to do this but also record the index at which the longest run began?
Use groupby, it group elements by value:
from itertools import groupby
group = groupby([1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1])
print max(group, key=lambda k: len(list(k[1])))
And here is the code in action:
>>> group = groupby([1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1])
>>> print max(group, key=lambda k: len(list(k[1])))
(2, <itertools._grouper object at 0xb779f1cc>)
>>> group = groupby([1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 3, 3, 3, 3, 3])
>>> print max(group, key=lambda k: len(list(k[1])))
(3, <itertools._grouper object at 0xb7df95ec>)
From python documentation:
The operation of groupby() is similar
to the uniq filter in Unix. It
generates a break or new group every
time the value of the key function
changes
# [k for k, g in groupby('AAAABBBCCDAABBB')] --> A B C D A B
# [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D
If you also want the index of the longest run you can do the following:
group = groupby([1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 3, 3, 3, 3, 3])
result = []
index = 0
for k, g in group:
length = len(list(g))
result.append((k, length, index))
index += length
print max(result, key=lambda a:a[1])
Loop through the list, keep track of the current number, how many times it has been repeated, and compare that to the most times youve seen that number repeated.
Counts={}
Current=0
Current_Count=0
LIST = [1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1]
for i in LIST:
if Current == i:
Current_Count++
else:
Current_Count=1
Current=i
if Current_Count>Counts[i]:
Counts[i]=Current_Count
print Counts
If you want it for just any element (i.e. the element with the most repetitions), you could use:
def f((v, l, m), x):
nl = l+1 if x==v else 1
return (x, nl, max(m,nl))
maxrep = reduce(f, l, (0,0,0))[2];
This only counts continuous repetitions (Result for [1,2,2,2,1,2] would be 3) and only records the element with the the maximum number.
Edit: Made definition of f a bit shorter ...
This is my solution:
def longest_repetition(l):
if l == []:
return None
element = l[0]
new = []
lar = []
for e in l:
if e == element:
new.append(e)
else:
if len(new) > len(lar):
lar = new
new = []
new.append(e)
element = e
if len(new) > len(lar):
lar = new
return lar[0]
-You can make new copy of the list but with unique values and a corresponding hits list.
-Then get the Max of hits list and get from it's index your most repeated item.
oldlist = ["A", "B", "E", "C","A", "C","D","A", "E"]
newlist=[]
hits=[]
for i in range(len(oldlist)):
if oldlist[i] in newlist:
hits[newlist.index(oldlist[i])]+= 1
else:
newlist.append(oldlist[i])
hits.append(1);
#find the most repeated item
temp_max_hits=max(hits)
temp_max_hits_index=hits.index(temp_max_hits)
print(newlist[temp_max_hits_index])
print(temp_max_hits)
But I don't know is this the fastest way to do that or there are faster solution.
If you think there are faster or more efficient solution, kindly inform us.
I'd use a hashmap of item to counter.
Every time you see a 'key' succession, increment its counter value. If you hit a new element, set the counter to 1 and keep going. At the end of this linear search, you should have the maximum succession count for each number.
This code seems to work:
l = [1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1]
previous = None
# value/repetition pair
greatest = (-1, -1)
reps = 1
for e in l:
if e == previous:
reps += 1
else:
if reps > greatest[1]:
greatest = (previous, reps)
previous = e
reps = 1
if reps > greatest[1]:
greatest = (previous, reps)
print greatest
i write this code and working easly:
lst = [4,7,2,7,7,7,3,12,57]
maximum=0
for i in lst:
count = lst.count(i)
if count>maximum:
maximum=count
indexx = lst.index(i)
print(lst[indexx])

Categories