Python sum up a set of array - python

The objective of task required to produce an array output such that output[i] is equal to the sum of all the elements of nums except nums[i].
Eg: given [6,7,8,9], return [24,23,22,21].
Input = [6,7,8,9]
The calculation behind is
0+7+8+9 = 24
6+0+8+9 = 23
6+7+0+9 = 22
6+7+8+0 = 21
Output = [ 24, 24, 22, 21 ]

You can use list comprehension:
In [1]: a = [6,7,8,9]
In [2]: s = sum(a)
In [3]: [s - i for i in a]
Out[3]: [24, 23, 22, 21]

Use numpy broadcasting + vectorised operations for this:
import numpy as np
x = np.array([6,7,8,9])
y = np.sum(x) - x
# array([24, 23, 22, 21])

You can use a for loop and python's inbuilt sum function
a = [6,7,8,9] #your input array
b = [] # initialise an empty list
for index in range(len(a)): #iterate through the list's length
b.append( sum( a[0:index] + a[index+1:] ) ) #add to two parts before and
# after the index
print(b)

Related

How can I compare elements in same list and append to other list ? (Python)

I want to compare elements in same list and append to other list but I have some problems.
For example:
a=[3,4,21,36,10,28,35,5,24,42]
c=[]
I want to do this:
4>3 append to other list.
21>4 append to other list.
36>21 append to other list.
28>10 but don't append this to other list because 36 is bigger than 28.
The result should be c=[4,21,36,42].
I tried this code:
b=0
d=1
while len(a)>b and len(a)>d:
if a[d]>a[b]:
c.append(a[d])
b+=1
d+=1
But it instead gives me:
c=[4, 21, 36, 28, 35, 24, 42]
Try this :
a=[3,4,21,36,10,28,35,5,24,42]
c = []
for x in range(1,len(a)):
count = 0
for y in range(x):
if a[x] > a[y]:
count = count + 1
if count == x:
c.append(a[x])
print(c)
you can iterate and check
currentList = [3,4,21,36,10,28,35,5,24,42]
newList = []
current_low = currentList[0]-1 # initialse current_low as [(first element of list) - 1]
for value in currentList:
if value > current_low:
newList.append(value)
current_low = value
>>>print(newList)
[3, 4, 21, 36, 42]
It took a moment to realize you want numbers that are less than ALL previous numbers, not just the number before it.
If you want to do this with a list comprehension, you could do:
c = [a[i] for i in range(1,len(a)) if a[i] > max(a[:i])]
Result: [4, 21, 36, 42]
If, however, you changed your mind and decided you wanted numbers greater than their previous number, you could do:
c = [j for (i,j) in filter(lambda x: x[0] < x[1], zip(a, a[1:]))]
Result: [4, 21, 36, 28, 35, 24, 42]

Remove values from numpy array closer to each other

Actually i want to remove the elements from numpy array which are closer to each other.For example i have array [1,2,10,11,18,19] then I need code that can give output like [1,10,18] because 2 is closer to 1 and so on.
In the following is provided an additional solution using numpy functionalities (more precisely np.ediff1d which makes the differences between consecutive elements of a given array. This code considers as threshold the value associated to the th variable.
a = np.array([1,2,10,11,18,19])
th = 1
b = np.delete(a, np.argwhere(np.ediff1d(a) <= th) + 1) # [1, 10, 18]
Here is simple function to find the first values of series of consecutives values in a 1D numpy array.
import numpy as np
def find_consec(a, step=1):
vals = []
for i, x in enumerate(a):
if i == 0:
diff = a[i + 1] - x
if diff == step:
vals.append(x)
elif i < a.size-1:
diff = a[i + 1] - x
if diff > step:
vals.append(a[i + 1])
return np.array(vals)
a = np.array([1,2,10,11,18,19])
find_consec(a) # [1, 10, 18]
Welcome to stackoverflow. below is the code that can answer you question:
def closer(arr,cozy):
result = []
result.append(arr[0])
for i in range(1,len(arr)-1):
if arr[i]-result[-1]>cozy:
result.append(arr[i])
print result
Example:
a = [6,10,7,20,21,16,14,3,2]
a.sort()
closer(a,1)
output : [2, 6, 10, 14, 16, 20]
closer(a,3)
Output: [2, 6, 10, 14, 20]

Using list comprehension to store the maximum seen value

Is it possible to do the below with list comprehension? Trying to store the maximum value that has been seen at any given point through the loop.
def test(input):
a = input[0]
b = []
for i in input:
a = max(i,a)
b.append(a)
return b
print test([-5,6,19,4,5,20,1,30])
# returns [-5, 6, 19, 19, 19, 20, 20, 30]
You can use itertools.accumulate with the max builtin in Python 3:
from itertools import accumulate
lst = [-5,6,19,4,5,20,1,30]
r = list(accumulate(lst, max)) #[i for i in accumulate(lst, max)]
print(r)
# [-5, 6, 19, 19, 19, 20, 20, 30]
What you present here is a typical form of what is known in functional programming as scan.
A way to do this with list comprehension that is inefficient is:
[max(input[:i]) for i in range(1,n+1)]
But this will run in O(n2).
You can do this with list comprehension given you use a function with side effects: like the following:
def update_and_store(f,initial=None):
cache = [initial]
def g(x):
cache[0] = f(cache[0],x)
return cache[0]
return g
You can then use:
h = update_and_store(max,a[0])
[h(x) for x in a]
Or you can use a dictonaries setdefault() like:
def update_and_store(f):
c = {}
def g(x):
return c.setdefault(0,f(c.pop(0,x),x))
return g
and call it with:
h = update_and_store(max)
[h(x) for x in a]
like #AChampion says.
But functions with side-effects are rather unpythonic and not declarative.
But you better use a scanl or accumulate approach like the one offered by itertools:
from itertools import accumulate
accumulate(input,max)
If using NumPy is permitted, then you can use NumPy:
import numpy as np
np.maximum.accumulate([-5,6,19,4,5,20,1,30])
# array([-5, 6, 19, 19, 19, 20, 20, 30])

How do I convert this into a comprehension? (Python)

This function produces the sum of the first n values, the sum of the second n values...etc.
Here is the function:
def collect_sum(iterable,n):
for e in range(1,len(ite)+1):
if e%n==0:
yield sum(iterable[e-n:e])
for i in c_sum(range(1,21),5):
print(i,end=' ')
This is supposed to return 15, 40, 65. When I use a list comprehension, it returns 0, 30, 40.
def collect_sum(i,n):
return (sum(g) for (_,g ) in groupby(i,key=lambda _,c=count():floor(next(c)/n)))
for v in collect_sum(range(1,21),5):
print(v)
Produces:
15
40
65
90
>>>
# generator version
def collect_sum(iterable,n):
for e in range(1,len(iterable)+1):
if e%n==0:
yield sum(iterable[e-n:e])
# list comprehension version
def collect_sum(iterable,n):
return [sum(iterable[e-n:e]) for e in range(1,len(iterable)+1) if e%n==0]
for i in collect_sum(range(1,21),5):
print(i,end=' ')
Using itertools.islice:
   
In [28]: n=5
In [29]: from itertools import islice
In [30]: lis=range(1,21)
In [31]: it=iter(lis)
In [33]: [sum(islice(it,n)) for _ in xrange(len(lis)/n) ]
Out[33]: [15, 40, 65, 90]

Python: Partial sum of numbers [duplicate]

This question already has answers here:
How to find the cumulative sum of numbers in a list?
(25 answers)
Closed 8 years ago.
can you help me with code which returns partial sum of numbers in text file?
I must import text file, then make a code for partial sums without tools ..etc.
My input:
4
13
23
21
11
The output should be (without brackets or commas):
4
17
40
61
72
I was trying to make code in python, but could only do total sum and not partial one.
If i use the += operator for generator, it gives me an error!
Well, since everyone seems to be giving their favourite idiom for solving the problem, how about itertools.accumulate in Python 3:
>>> import itertools
>>> nums = [4, 13, 23, 21, 11]
>>> list(itertools.accumulate(nums))
[4, 17, 40, 61, 72]
There are a number of ways to create your sequence of partial sums. I think the most elegant is to use a generator.
def partial_sums(iterable):
total = 0
for i in iterable:
total += i
yield total
You can run it like this:
nums = [4, 13, 23, 21, 11]
sums = list(partial_sums(nums)) # [ 4, 17, 40, 61, 72]
Edit To read the data values from your file, you can use another generator, and chain them together. Here's how I'd do it:
with open("filename.in") as f_in:
# Sums generator that "feeds" from a generator expression that reads the file
sums = partial_sums(int(line) for line in f_in)
# Do output:
for value in sums:
print(value)
# If you need to write to a file, comment the loop above and uncomment this:
# with open("filename.out", "w") as f_out:
# f_out.writelines("%d\n" % value for value in sums)
numpy.cumsum will do what you want.
If you're not using numpy, you can write your own.
def cumsum(i):
s = 0
for elt in i:
s += elt
yield s
try this:
import numpy as np
input = [ 4, 13, 23, 21, 11 ]
output = []
output.append(input[0])
for i in np.arange(1,len(input)):
output.append(input[i] + input[i-1])
print output
Use cumulative sum in numpy:
import numpy as np
input = np.array([4, 13, 23, 21 ,11])
output = input.cumsum()
Result:
print output
>>>array([ 4, 17, 40, 61, 72])
Or if you need a list, you may convert output to list:
output = list(output)
print output
>>>[4, 17, 40, 61, 72]
This is an alternative solution using reduce:
nums = [4, 13, 23, 21, 11]
partial_sum = lambda a, b: a + [a[-1] + b]
sums = reduce(partial_sum, nums[1:], nums[0:1])
Pluses in lambda are not the same operator, the first one is list concatenation and the second one is sum of two integers. Altough Blckknght's may be more clear, this one is shorter and works in Python 2.7.
something like this:
>>> lst = [4, 13, 23, 21 ,11]
>>> [sum(lst[:i+1]) for i, x in enumerate(lst)]
[4, 17, 40, 61, 72]

Categories