Multiplying all negative values in a list - python

can someone help me write code in Python for this problem?
x = [10,-5,6,-7,2,4,-9,12,-55,33,44,77]
Write up some code to multiply only the negative values. Print the result of these multiplications. Include a loop of some kind as well as an if-statement to grab just the negative numbers.
This is what I have so far:
x = [10,-5,6,-7,2,4,-9,12,-55,33,44,77]
for num in x:
if num < 0:
print (num, end = "")

IIUC, here's one way via reduce
from functools import reduce
x = [10, -5, 6, -7, 2, 4, -9, 12, -55, 33, 44, 77, -1]
result = reduce(lambda x, y: x*y, (i for i in x if i < 0))
OUTPUT:
17325

You almost got it. I think they want you to do a simple script:
x = [10,-5,6,-7,2,4,-9,12,-55,33,44,77]
result = 1
for num in x:
if num < 0:
result = result * num
# or result *= num
print(result)

With basic arithmetic and closest to your original version:
total = 0 if len(x)==0 else 1
for i in x:
if i < 0:
total *= i
print(total, end = "")
17325
borrowing from https://stackoverflow.com/a/13843424/1248974

Related

Array task. Finding last two negative numbers in array

Search for the numbers of the last two consecutive negative elements in an array. The length of the array is entered from the keyboard. Float type.
my code is:
import math
import numpy
import random
#i = (random.uniform(-1000, 1000))
o = []
a = []
n = int(input())
n += 1
l = 0
sh = 1
m2 = n
m = n-1
m=int(m)
for i in range(n):
x = (random.uniform(-1000, 1000))
a.append(x)
for i in range(m):
otric = a.pop(m)
otric = int(otric)
a.insert(otric,int(m+1))
if otric < 0:
o.append(otric)
m -= 1
if len(o) > 2: break
print(a)
print(o)
and this doesn't work, idk how to fix it.. please help
Use zip to get all consecutive negative numbers and return the last element of the resulting list:
a = [random.uniform(-1000, 1000) for _ in range(n)]
>>> [(x,y) for x,y in zip(a, a[1:]) if x<0 and y<0][-1]
(-696.9270891497699, -612.4999984966855)
Iterate the list in reverse and when a value is negative also grab the next one and see if it is the pair we're looking for:
lst = [1, -7, -8, 1, 1, -1, 1, -2, -3, 1, -4, 1, -5, 1, 1]
it = reversed(lst)
for a in it:
if a < 0:
b = next(it, 0)
if b < 0:
print(b, a)
break

Generating sequences a recursively defined math string in Python

I have a sequence defined:
and my current code:
a = [1]
i=1
while a[-1] < 50:
if a[-1] + 5*i < 50:
a.append(a[-1] + 5*i)
i+=1
else:
break
Output:
[1, 6, 16, 31]
can it be done more elegantly and optimally?
One liners using accumulate
Solution 1: Creates n Terms
from itertools import accumulate
def seq(n):
" Creates n terms of sequence"
return list(accumulate(range(1, n+1), lambda acc, v: acc + 5*(v-1)))
print(seq(5)) # Generate first 5 terms
# Out: [1, 6, 16, 31, 51]
Solution 2--Creates up to Max Value
from itertools import accumulate, takewhile, count
def seq_gen(MAX):
" terms up to value MAX "
return list(takewhile(lambda v: v<=MAX, accumulate(count(start=1), lambda acc, v: acc + 5*(v-1))))
print(seq_gen(50)) # Generate to a maximum value of 50
# Out: [1, 6, 16, 31]
I'd write it with a generator:
import itertools
def gen_sequence(maximum):
n = 1
for i in itertools.count(0):
n = n + 5 * i
if n > maximum: break
yield n
if __name__ == "__main__":
print(list(gen_sequence(50))) # => [1, 6, 16, 31]
Or if you don't want to provide an upper limit, you can generate infinitely and let the caller dynamically decide when to quit. This enables the caller to step forward a few iterations and resume later or use itertools.takewhile to immediately pick up to a limit:
from itertools import count, takewhile
def gen_sequence():
n = 1
for i in count(0):
n = n + 5 * i
yield n
if __name__ == "__main__":
print(list(takewhile(lambda x: x < 50, gen_sequence()))) # => [1, 6, 16, 31]
Whichever way you do it, it's a good idea to put the logic in a function with parameters and check the termination condition once. Ideally come up with a better name for the sequence than gen_sequence, which is rather ambiguous.
This code is just like yours without useless if and break
a = [1]
i=1
while a[-1] + 5*i < 50:
a.append(a[-1] + 5*i)
i+=1
Here's the way that I would write it:
def seq(a, n, lst=[]):
a = a + 5 * (n - 1)
n += 1
if a < 50:
lst.append(a)
seq(a, n)
return lst
print(list(seq(1, 1)))
A really cute one liner:
def seq(n):
return([(1+sum(i for i in range(0,5*j,5))) for j in range(1,n+1)])
print(seq(5))
[1, 6, 16, 31, 51]
I didn't quite understand what exactly the function you are looking for returns,
but here's a general implementation in case you are looking to get the number An
def func(n):
if n==1:
return 1
return (func(n-1) + 5*(n-1))

Python for loop and function

Am new to python and I have been trying to solve this problem but it does not seem to work as intended. your help is highly appreciated:
Given two numbers X and Y, write a function that:
returns even numbers between X and Y, if X is greater than Y
else returns odd numbers between x and y
.
def number(x,y):
if x > y:
for i in range(x,y):
if i%2 == 0:
list = []
return list.append[i]
else:
for i in range(x,y):
if i%2 == 1:
list = []
return list.append[i]
print(number(10,2))
Try this code it's working as per your need.
def number(x,y):
num= []
if x > y:
for i in range(y,x):
if i%2 == 0:
num.append(i)
else:
for i in range(x,y):
if i%2 == 1:
num.append(i)
return num
print(number(2,10))
print(number(10,2))
The outputs are:
[3, 5, 7, 9]
[2, 4, 6, 8]
Let me know if this doesn't serve your purpose.
And it is done. Basically if x > y, you need to switch the first range. You append the items normally(using () instead of []), and then return the full list, got it?
def number(x,y):
list = []
if x > y:
for i in range(y,x):
if i%2 == 0:
list.append(i)
else:
for i in range(x,y):
if i%2 == 1:
list.append(i)
return list
print(number(10,2))
Working sample: https://py3.codeskulptor.org/#user302_nwBq00w56n_1.py
Instead of testing for oddness/evenness all the time, use range(start,stop[,step]) with a step of 2 starting with a (corrected, known) odd/even number:
def number(x,y):
if x > y:
if y%2 == 1: # y is smaller && odd
y += 1 # make even
return list(range(y,x,2)) # x is > y - start from y to x
else: # this is strictly not needed - but more verbose intention-wise
if x%2 == 0: # is even
x += 1 # make odd
return list(range(x,y,2))
print(number(10,32))
print(number(10,2))
You need to also switch x and y if x > y
you do not need to iterate a range and add its element to a list iteratively - simply stuff the range-sequence into the list(sequence) constructor and return it
Output:
[11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31]
[2, 4, 6, 8]
It's so easy to do, and there are several ways to do what do you want, so i show you two ways to do that, first an understandable way and second an easy way ok let's start:-
First example
def number(x,y):
list = [] #firstly create a list
if x > y: #if x was greater than y
for num in range(y, x): # a loop for searching between them
if(num % 2 == 0): # if the number was even add it to list
list.append(num)
elif y > x: #if y was greater than x
for num in range(x, y): # a loop for searching between them
if(num % 2 != 0): # if the number was not even add it to list
list.append(num)
return list
print(number(10, 20))
print(number(20, 10))
#[11, 13, 15, 17, 19]
#[10, 12, 14, 16, 18]
Second example
number = lambda x, y : [n for n in range(y, x) if n%2 == 0] if x > y else [n for n in range(x, y) if n%2 != 0]
print(number(10, 20))
print(number(20, 10))
#[11, 13, 15, 17, 19]
#[10, 12, 14, 16, 18]
Note : But be sure that in both of my answers the x number is inclusive(exists in searching function) and the y number is exclusive, so if you wanted to make both of them inclusive so make loops ...(x, y+1)... and if you wanted to make both of them exclusive just change loops to ...(x+1, y)....
Knowing that 2 % 2 == 0 we then can just use if not 2 % 2 for evens since not 0 will evaluate to true, here it is with comprehension and in extended form
def something(x, y):
if x > y:
l = [i for i in range(y, x) if not i % 2]
else:
l = [i for i in range(x, y) if i % 2]
return l
print(something(10, 2))
print(something(2, 10))
~/python/stack$ python3.7 sum.py
[2, 4, 6, 8]
[3, 5, 7, 9]
Full loop:
def something(x, y):
l = []
if x > y:
for i in range(y, x):
if not i % 2:
l.append(i)
else:
for i in range(x, y):
if i %2:
l.append(i)
return l
Here in this i use the list comprehensions.list comprehension is a easy and readable technique in python.In this i include both x and y
def fun(x,y):
if x>y:
l=[i for i in range(y,x-1) if i%2==0]
return l.reverse()
else:
l=[i for i in range(x,y+1) if i%2!=0]
return l

Find Sum of list with condition

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)

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