Find Sum of list with condition - python

I am stuck at a problem.
I have a List L = [1,2,3,4,5,6,7,8,9]
I want to find the sum of elements in lists such that, if the sum exceeds's 25. I want to get the previous sum.
for eg. 1+2+3+4+5+6+7=28, 28>25. Therefore i want a final variable sum as 21.
i am doing it using for-if combination, but i don't want to use if . Is there a better way of doing this? below is my code.
L = [1,2,3,4,5,6,7,8,9]
summ = 0
for val in L:
summ+= val
if summ > 25:
summ-=val

I think what bothers you is the summ-=val part, not the if. And there is a one line solution with reduce.
>>> from functools import reduce
>>> L = [1,2,3,4,5,6,7,8,9]
>>> reduce(lambda x, y: x + y if x + y <= 25 else x, L)
21
https://docs.python.org/3/library/functools.html#functools.reduce

You can use a while loop:
L = [1,2,3,4,5,6,7,8,9]
i = 0
s = 0
while i < len(L) and s + L[i] < 25:
s += L[i]
i += 1

Using pandas, take the cumulative sum on a series consisting of the numbers in the list. Assign the value NaN to any any cumulative sum over max_value. Fill forward the result and convert back to a list of integers.
import pandas as pd
max_val = 25
a = range(1, 10)
s = pd.Series(a).cumsum()
s.loc[s > max_val] = np.nan
>>> s.ffill().astype(int).tolist()
[1, 3, 6, 10, 15, 21, 21, 21, 21]

How about integrating the condition into the mathematical expression:
L = [1,2,3,4,5,6,7,8,9]
summ = 0
for val in L:
summ = summ+val*(summ+val <= 25)

Related

how to find how many times the highest number in a list appeared using python? [duplicate]

This question already has answers here:
No. of occurrences of maximum item in a list
(4 answers)
Closed 2 years ago.
e.g.
if a list is: list = [1, 2, 3, 4, 4]
how to count the amount of times number 4 appeared, while not specifying it. using max(list) or something like that.
Try this using max:
l = [1,2,3,4,4]
num = max(l, key=lambda x:l.count(x)) # num will be 4
the you can get the count of num.
l.count(num) # this wil returns 2
in the other hand as #buddemat said(Here), it is better to:
from collections import Counter
l = [1,2,3,4,4]
c = Counter(l)
c.most_common()[0]
will give you
(4,2) # 4 is a maximum number and 2 is number of occurrence.
Also note that:
DO NOT use list as a variable name, list is predefined in python and you will override its own functionality.
While straightforward solution is to first find the maximum and then count it, here is how you can do both in one pass:
import functools
list = [1, 2, 3, 4, 4]
(max, count) = functools.reduce (
lambda x, y:
(y, 1) if x [0] is None or x [0] < y
else x if x [0] > y
else (x [0], x [1] + 1),
list,
(None, 0))
print (max, count)
This solution returns None, 0 for empty list.
def get_max_occ(l):
max_i = None
for i in l:
if max_i is not None:
if i > max_i:
max_i = i
occ = 1
else:
occ += 1
else:
max_i = i
occ = 1
return occ
First, find the maximum and use count
l1 = [1, 2, 3, 4, 4]
maximum = max(l1)
count = l1.count(maximum)
You can replace the maximum function by yourself. If you don't like to use the built-in function by following the ways
def max(l1):
maximum = l1[0]
for el in l1:
if maximum< el:
maximum = el
return maximum
The above function will check each element of the list iteratively.
def maximum(l1):
if len(l1) == 1:
return l1[0]
if len(l1) == 2:
if l1[0]> l1[1]:
return l1[0]
else:
return l1[1]
else:
max1 = maximum(l1[:len(l1)//2])
max2 = maximum(l1[len(l1)//2:])
if max1 > max2:
return max1
else:
return max2
The above function is using the divide and conquer approach to find the maximum which time complexity is logn

Find number of times a number is followed by a larger number in a list

I have this function to find the number of times a number is followed by a larger number in a list. Is there another more "pythonic" way this could be done? I am using Python 3.7.0.
Thanks in advance.
def find_greater_numbers(arr):
count = 0
i = 0
j = 1
while i < len(arr):
while j < len(arr):
if arr[j] > arr[i]:
count += 1
j+=1
j = i+1
i+=1
return count
find_greater_numbers([6,1,2,7]]) # returns 4
It's a bit unclear if you mean immediately followed, or followed at any later index
In the first case, this one liner:
sum(x < y for x,y in zip(arr[:-1],arr[1:])) # answer is 2
In the second, this one:
sum(any(x < y for y in arr[i:]) for i,x in enumerate(arr)) # answer is 3
And if you want to count the number of exact such pairs (like what your actual code seems to be doing):
sum(x < y for i,x in enumerate(arr) for y in arr[i:]) # answer is 4
Use map to get the list of True/False for each pair of number in the list depending on the condition if x < y. This list is being generated using the for loop. After getting the list, filter the number of 'True' in the list. Then create a single list using itertools.chain.from_iterable() function and find its length.
import itertools
arr = [6, 1, 2, 7]
num = len(list(itertools.chain.from_iterable(list(filter(lambda x: x , map(lambda x, y: x<y, arr[:-i], arr[i:]))) for i, x in enumerate(arr))))
print(num)

How do I get smallest postitive integer not present in the array

I am trying to find out smallest positive number not present in the list a
def smallitem(a):
a = sorted(set(a))
lst = []
for item in a:
item + = 1
if item not in a:
lst.append(item)
continue
mst = []
for item in lst:
if item < 1:
item += 1
if item not in a:
mst.append(item)
continue
n = 0
if mst:
n = min(mst)
return n or min(lst)
I think I have got the solution but it doesnt look correct to me the way I have done it.
for example:
smallitem([-1, -3]) # 1
smallitem([1,3,6,4,1,2, 87]) # 5
You can convert the list to a set and then keep incrementing a positive integer from 1 until it is not found in the set:
def smallitem(a):
set_a = set(a)
i = 1
while i in set_a:
i += 1
return i
Perhaps there's a lighter way do this.
The time complexity is always O(n).
def small_item(a):
s = set(a)
for i in range(1, max(s)):
if i not in s:
return i
return max(max(s) + 1, 1)
print small_item([1,3,6,4,1,2, 87])
print small_item([-1, -3])
Here's anther way to do this:
def smallitem(l):
l = list(set(sorted(l)))
x = l[0]
for i in l:
if i != x and x >= 1:return x
x += 1
return 1
Testing:
>>> smallitem([-3, -1])
1
>>> smallitem([1, 3, 6, 4, 1, 2, 87])
5
>>>

Using sum() to print the sum of even numbers in a list

I am having trouble finding information on using sum to take from a list. I know how to use sum with range, for example:
sum = 0
for i in range(50):
sum=sum + i
print (sum)
But I can't get my code to work when I am using a list such as [1, 2, 6, 7, 8, 10] and taking the even numbers using sum. Can anyone point me in the right direction?
You can filter out odd-values:
def is_even(x):
# if the remainder (modulo) is 0 then it's evenly divisible by 2 => even
return x % 2 == 0
def sum_of_evens(it):
return sum(filter(is_even, it))
>>> sum_of_evens([1,2,3,4,5])
6
Or if you prefer a conditional generator expression:
>>> lst = [1,2,3,4,5]
>>> sum(item for item in lst if item % 2 == 0)
6
Or the explicit (long) approach:
lst = [1,2,3,4,5]
sum_ = 0
for item in lst:
if item % 2 == 0:
sum_ += item
print(sum_) # 6

Finding Avg of all 2-Digit in a list

I'm trying to find the avg of list but only when n >= 10 (two digit numbers, my original list is limited to 100).
Here's what I have right now:
# Calculate average of all two-digit numbers (10-99)
grade_list = [10, 11, 12, 13, 14, 15]
def calcAvg(grade_list):
while n > 10:
total = sum(grade_list)
n = total % len(grade_list)
print_list = n
return print_list
I get that I have to find the total sum of the list when n > 10 and then dividing by the length (only > 10, my original list has single digit elements, so I'd like to avoid them).
But when I run it, I get an error saying: local variable 'n' referenced before assignment
Any help on how to structure this function to achieve the end results (sum/total of only 2-digit elements = avg)
Thanks!
I'd either collect the good grades and use sum/len, or use the mean function:
>>> grade_list = [1, 2, 10, 11, 12, 13, 14, 15]
>>> good = [g for g in grade_list if g > 10]
>>> sum(good) / len(good)
13.0
>>> import statistics
>>> statistics.mean(g for g in grade_list if g > 10)
13.0
def calcAvg(grade_list):
my_list = []
total, count = 0,0
for n in grade_list:
if 10 <= n <= 99:
total += n
if not total:
return None
return total/count
Here is a clean way of doing it:
def calc_avg(lst):
filtered_lst = filter(lambda x: 10 < x < 100, lst)
return sum(filtered_lst) / len(filtered_lst)
So you should use a for loop instead of a while loop. Instead of having two for loops and making a new list, you could just account for the sum inside the first for loop. I demonstrate this below.
def calcAvg(grade_list):
sum = 0;
count = 0;
for n in grade_list:
if 10 <= n <= 99:
sum = sum + n
count = count + 1
return sum/count
I think you should manually go over the code step by step and try to understand what is wrong. Meanwhile this may give you some hints
# Calculate average of all two-digit numbers (10-99)
def calcAvg(alist):
count=total=0
for i in alist:
if 9 < i < 100:
total += i
count += 1
return total/count
Since Python 3.4 there is a statistics module.
So you just need to filter out numbers in range <10,100), for example with a list comprehension, and then pass this filtered list to the mean function. Simple as that.
from statistics import mean
numbers = [1, 20, 30, 50]
mean([n for n in numbers if n >= 10 and n < 100])
>>> 33.333333333333336
You could do this fairly simply with a list comprehension
>>> grades = [1, 2, 10, 11, 12, 13, 14, 15, 120, 122, 320]
>>> lst = [v for v in grades if 10 <= v < 100]
>>> sum(lst)/len(lst)
12

Categories

Resources