i have 2 lists
a=[[2,3,5],[3,6,2],[1,3,2]]
b=[4,2,1]
i want the output to be:
c=[[8,12,20],[6,12,4],[1,3,2]]
At present i am using the following code but its problem is that the computation time is very high as the number of values in my list are very large.The first list of list has 1000 list in which each list has 10000 values and the second list has 1000 values.Therefore the computation time is a problem.I want a new idea in which computation time is less.The present code is:
a=[[2,3,5],[3,6,2],[1,3,2]]
b=[4,2,1]
c=[]
s=0
for i in b:
c1=[]
t=0
s=s+1
for j in a:
t=t+1
for k in j:
if t==s:
m=i*k
c1.append(m)
c.append(c1)
print(c)
Use zip() to combine each list:
a=[[2,3,5],[3,6,2],[1,3,2]]
b=[4,2,1]
[[m*n for n in second] for m, second in zip(b,a)]
You can use numpy :
>>> import numpy as np
>>> a=np.array([[2,3,5],[3,6,2],[1,3,2]])
>>> b=np.array([4,2,1])
>>> a*np.vstack(b)
array([[ 8, 12, 20],
[ 6, 12, 4],
[ 1, 3, 2]])
Or as #csunday95 suggested as a more optimized way you can use transpose instead of vstack :
>>> (a.T*b).T
array([[ 8, 12, 20],
[ 6, 12, 4],
[ 1, 3, 2]])
This may not be faster, but it's a neater way of doing it :)
c = []
b_len = len(b)
for i in range(len(a)):
b_multiplier = b[i%b_len]
c.append([x*b_multiplier for x in a[i]])
Alternate short way now I've actually read the question properly and realised a and b are the same length:
c = [[x*b[i] for x in a[i]] for i in range(len(a))]
Related
I would like to make the following sum given two lists:
a = [0,1,2,3,4,5,6,7,8,9]
b = [2,3,5]
The result should be the sum of the every b element of a like:
b[0] = 2 so the first sum result should be: sum(a[0:2])
b[1] = 3 so the second sum result should be: sum(a[2:5])
b[2] = 5 so the third sum result should be: sum(a[5:10])
The printed result: 1,9,35
You can make use of np.bincount with weights:
groups = np.repeat(np.arange(len(b)), b)
np.bincount(groups, weights=a)
Output:
array([ 1., 9., 35.])
NumPy has a tool to do slice based sum-reduction with np.add.reduceat -
In [46]: np.add.reduceat(a,np.cumsum(np.r_[0,b[:-1]]))
Out[46]: array([ 1, 9, 35])
Hard to compete with the np.bincount solution, but here's another nice way to approach it with np.cumsum:
strides = [0] + np.cumsum(b).tolist() # [0, 2, 5, 10]
stride_slices = zip(strides[:-1], strides[1:]) # [(0, 2), (2, 5), (5, 10)]
[sum(a[s[0]: s[1]]) for s in stride_slices]
# [1, 9, 35]
You mean something like this?
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b = [2, 3, 5]
def some_function(a, b): # couldnt come up with a name :D
last_index = 0
for i in b:
print(sum(a[last_index:last_index + i]))
last_index += i
some_function(a, b)
You can use a list comprehension with sum:
a=[0,1,2,3,4,5,6,7,8,9]
b=[2,3,5]
r = [sum(a[(k:=sum(b[:i])):k+j]) for i, j in enumerate(b)]
Output:
[1, 9, 35]
I would like to return the duplicates in two different 2d lists. But I'm having trouble figuring out what code to write. For example I would like variable "a" to compare to variable "b" and return the duplicates. Here are my two 2d list below.
a = [[2,3,6,8],[4,5,7,8,10],[15,17,21,22],[12,13,14,23,25]]
b = [[4,5,6],[15,17,21,22],[2,3,4],[2,3,6,8],[5,7,8,12,15],[7,12,14,17,32],[5,6,7,12,14]]
I would like my results to be:
c = [[2,3,6,8],[15,17,21,22]]
You just need to check if a list in a is also in b or not.
a = [[2,3,6,8],[4,5,7,8,10],[15,17,21,22],[12,13,14,23,25]]
b = [[4,5,6],[15,17,21,22],[2,3,4],[2,3,6,8],[5,7,8,12,15],[7,12,14,17,32],[5,6,7,12,14]]
c=[]
for i in a:
if i in b:
c.append(i)
print(c)
Output:
[[2, 3, 6, 8], [15, 17, 21, 22]]
This should work, it should get you started -
import itertools
#Input lists
a = [[2,3,6,8],[4,5,7,8,10],[15,17,21,22],[12,13,14,23,25]]
b = [[4,5,6],[15,17,21,22],[2,3,4],[2,3,6,8],[5,7,8,12,15],[7,12,14,17,32],[5,6,7,12,14]]
#Take a product of both the lists ( a X b )
z = itertools.product(a,b)
#Uncomment the following to see what itertools.product does
#[i for i in z]
#Return only the elements which the pair of the same element repeats (using string match)
[i[0] for i in z if str(i[0])==str(i[1])]
[[2, 3, 6, 8], [15, 17, 21, 22]]
one liner list comprehension approach:
dups = [i for i in a if i in b]
output:
[[2, 3, 6, 8], [15, 17, 21, 22]]
Try this:
a = [[2,3,6,8],[4,5,7,8,10],[15,17,21,22],[12,13,14,23,25]]
b = [[4,5,6],[15,17,21,22],[2,3,4],[2,3,6,8],[5,7,8,12,15],[7,12,14,17,32],[5,6,7,12,14]]
c = []
for i in a + b:
if (a + b).count(i) > 1 and i not in c:
c.append(i)
#mulaixi's answer is OK but in output list you may see duplicates.
Given a list containing monthly numerical data, how can I easily convert this into quarterly data?
x= [5,8,3,4,5,6,1,2,5,3,11,8] #monthly data for Jan-Dec
Desired output:
[5+8+3, 4+5+6, 1+2+5, 3+11+8] #converted to quarterly data
I wanted to do something like [a+b+c for a,b,c in x] but x it says x is not iterable.
I don't think this is a duplicate. I am specifically looking for a list comprehension solution.
A list comprehension way:
[sum([x[i],x[i+1],x[i+2]]) for i in range(0,len(x),3)]
#[16, 15, 8, 22]
Or in a nicer way (thanks #JonClements):
[sum(x[i:i+3]) for i in range(0, len(x), 3)]
And a numpy way:
import numpy as np
np.sum(np.array(x).reshape(-1,3),axis=1)
#array([16, 15, 8, 22])
Not getting to crazy you could just slice them up and then work with each group
x= [5,8,3,4,5,6,1,2,5,3,11,8]
a, b, c, d = x[:3], x[3:6], x[6:9], x[9:12]
print(a, b, c, d)
(xenial)vash#localhost:~/python/stack_overflow$ python3.7 slice_q.py
[5, 8, 3] [4, 5, 6] [1, 2, 5] [3, 11, 8]
From here if you want to sum each group you could do something like this
lista = [a, b, c, d,]
for i in lista:
print(sum(i))
16
15
8
22
I have a function foo that returns an array with the shape (1000, 2)
how can I split it to two arrays a(1000) and b(1000)
I'm looking for something like this:
a;b = foo()
I'm looking for an answer that can easily generalize to the case in which the shape is (1000, 5) or so.
The zip(*...) idiom transposes a traditional more-dimensional Python list:
x = [[1,2], [3,4], [5,6]]
# get columns
a, b = zip(*x) # zip(*foo())
# a, b = map(list, zip(*x)) # if you prefer lists over tuples
a
# (1, 3, 5)
# get rows
a, b, c = x
a
# [1, 2]
Transpose and unpack?
a, b = foo().T
>>> a, b = np.arange(20).reshape(-1, 2).T
>>> a
array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18])
>>> b
array([ 1, 3, 5, 7, 9, 11, 13, 15, 17, 19])
You can use numpy.hsplit.
x = np.arange(12).reshape((3, 4))
np.hsplit(x, x.shape[1])
This returns a list of subarrays. Note that in the case of a 2d input, the subarrays will be shape (n, 1). Unless you wrap a function around it to squeeze them to 1d:
def split_1d(arr_2d):
"""Split 2d NumPy array on its columns."""
split = np.hsplit(arr_2d, arr_2d.shape[1])
split = [np.squeeze(arr) for arr in split]
return split
a, b, c, d = split_1d(x)
a
# array([0, 4, 8])
d
# array([ 3, 7, 11])
You could just use list comprehensions, e.g.
(a,b)=([i[0] for i in mylist],[i[1] for i in mylist])
To generalise you could use a comprehension within a comprehension:
(a,b,c,d,e)=([row[i] for row in mylist] for i in range(5))
You can do this simply by using zip function like:
def foo(mylist):
return zip(*mylist)
Now call foo with as much dimension as you have in mylist, and it would do the requisite like:
mylist = [[1, 2], [3, 4], [5, 6]]
a, b = foo(mylist)
# a = (1, 3, 5)
# b = (2, 4, 6)
So this is a little nuts, but if you want to assign different letters to each sub-array in your array, and do so for any number of sub-arrays (up to 26 because alphabet), you could do:
import string
letters = list(string.ascii_lowercase) # get all of the lower-case letters
arr_dict = {k: v for k, v in zip(letters, foo())}
or more simply (for the last line):
arr_dict = dict(zip(letters, foo()))
Then you can access each individual element as arr_dict['a'] or arr_dict['b']. This feels a little mad-scientist-ey to me, but I thought it was fun.
I have a list of integers (from 0 to N) and I need to create a new list which contains the indexes of each integer in the first list.
That is, given
s = [4, 2, 6, 3, 0, 5, 1]
determine r such that s[r[i]] = i
r = [4, 6, 1, 3, 0, 5, 2]
My current solution is
r = [s.index(i) for i in xrange(len(s))]
Is there a better way?
I assume that each integer in S appears exactly once. Your current solution will work, the problem is that s.index performs an O(N) search, making this an O(N**2) operation.
For a large list, I would expect the following code to be faster since it is O(N)
# initialise the whole list with some value
r = [-1]*N
for j, s_j in enumerate(s):
r[s_j] = j
# if any element of r is still -1 then you know it did not appear in s
It seems like a dictionary would be better for this:
s = [4, 2, 6, 3, 0, 5, 1]
r = dict((v,i) for i,v in enumerate(s))
testing:
>>> for i,_ in enumerate(s):
... print i, s[r[i]]
...
0 0
1 1
2 2
3 3
4 4
5 5
6 6
Personally the approach you showed is great.
Either a dictionary would work - that would be my first try:
r = {v:i for i, v in enumerate(s)}
Or if you have to use a list another approach is:
r = [x[0] for x in sorted(enumerate(s), key=lambda v:v[1])]
Are you allowed to use numpy ?
>>> import numpy as np
>>> s = np.array([4, 2, 6, 3, 0, 5, 1])
>>> s.argsort()
array([4, 6, 1, 3, 0, 5, 2], dtype=int64)
i did a simple benchmark with the timit module #10^6 iterations - 5 repetitions.
DaveP : 1.16 +/- 0.04s
koblas: 7.02s +/- 0.04s
Jon Clements: 1.82 +/- 0.02s
Zero Piraeus: 6.04 +/- 0.4s
and last but not least:
r=s[:]
[r[s[i]] for i in s]
my suggestion: 1.11 +/- 0.03s