How combine two list into list of list at python? - python

Let's say I have:
a = [10,14,16]
b = [0,1,2]
and I want combine a and b into one list, as shown below:
print c
[[10, 0], [14, 1], [16, 2]]
I have tried to merge the two lists:
a + b
[10, 14, 16, 0, 1, 2]
but it's not same as what I want to achieve.
How can I do that in Python?

This is what zip() is for:
>>> a = [10,14,16]
>>> b = [0,1,2]
>>> zip(a, b)
[(10, 0), (14, 1), (16, 2)]
Note that this would get you a list of tuples. In case you want a list of lists:
>>> [list(item) for item in zip(a, b)]
[[10, 0], [14, 1], [16, 2]]

You could use zip built in function. It's very efficient compared to manual implementation.
In [52]: c = list(zip(a,b))
In [53]: c
Out[53]: [(10, 0), (14, 1), (16, 2)]

a = [10,14,16]
b = [0,1,2]
c = []
for i in range(len(a)):
c.append([a[i], b[i]])
print c
Or in one line:
print [[a[i], b[i]] for i in range(len(a))]
Outputs:
[[10, 0], [14, 1], [16, 2]]

using a simple for loop?
a = [10,14,16]
b = [0,1,2]
c = []
for i in range(len(a)):
try:
c.append([a[i],b[i]])
except KeyError:
c.append([a[i]])
print c
or by using a generator:
c = [ [a[i],b[i]] for i in range(len(a))]

for small lists you can do a "for" loop:
a = [10,14,16]
b = [0,1,2]
for i in range(len(a)):
out[i] = [a[i],b[i]]
Or for longer list you can use pandas to create a dataframe:
import pandas as pd
df = pd.dataframe([a,b],columns = ['a','b'])
out = df.T.values.tolist()

import numpy as np
np.array(a+b).reshape(2,3).T.tolist()

Related

Sums of variable size chunks of a list where sizes are given by other list

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]

How do you compare and return duplicates in two different 2d list?

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.

python3 - Extending list of strings element-wise

So I have two list
A = ['astr1', 'astr2', 'astr3']
and
B = ['bstr11','bstr12']
now I want a final list which sould be a combination of two and will look like this,
C = [['astr1', 'bstr11','bstr12'], ['astr2', 'bstr11','bstr12'], ['astr3', 'bstr11','bstr12']]
I tried extending list A using for loop over B but since it happens on single elements as strings, extend doesn't work.
any leads ?
EDIT:
for i in range(len(A)):
A[i].extend(B)
You can use a list comprehension for this:
In [1]: a = [1,2,3]
In [2]: b = [11,12]
In [3]: c = [[e] + b for e in a]
In [4]: c
Out[4]: [[1, 11, 12], [2, 11, 12], [3, 11, 12]]

what is the most pythonic way to split a 2d array to arrays of each row?

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.

combining lists: three lists into one new list

I have three lists that contain x,y and z positions. For example:
x = [10,20,1]
y = [10,15,2]
z = [12,23,3]
I want to create a list using these that looks like:
xyz = [[10,10,12], [20,15,23], [1,2,3]]
These lists are huge (1 million entries).
What is a good way to do this?
Thanks!
You're looking for the zip builtin function:
>>> x = [10,20,1]
>>> y = [10,15,2]
>>> z = [12,23,3]
>>> zip(x, y, z)
[(10, 10, 12), (20, 15, 23), (1, 2, 3)]
This produces a list of tuples. If you absolutely need a list of lists, coerce those tuples manually:
>>> [list(t) for t in zip(x, y, z)]
[[10, 10, 12], [20, 15, 23], [1, 2, 3]]
Note that in Python 3, zip returns a lazy iterator instead of a list (the same as itertools.izip in Python 2). If your lists are that big, that may actually be preferable, but remember that iterators aren't subscriptable.
For Python 2.x you can use izip:
from itertools import izip
for a,b,c in izip(x,y,z):
# do something
This iterates across the lists instead of copying their data.
This is a manual way of doing it (if you're interested):
>>> xyz = []
>>> x = [10, 20, 1]
>>> y = [10, 15, 2]
>>> z = [12, 23, 3]
>>>
>>> for num in range(3): #Change 3 to however many numbers u want
... xyz.append([x[num], y[num], z[num]])
...
>>> print xyz
[[10, 10, 12], [20, 15, 23], [1, 2, 3]]
Hope this helps!

Categories