sorting nested list based on another lis - python

a = [[1,3,45,6,78,9],[2,6,5,88,3,4],[44,66,2,4,77,12]]
b = [4,6,3]
These are two lists in python, now each element in the first list a corresponds to the element in the list b with the same index. i.e a[0]:4,a[1]:6,a[2]:3 and so on.
Now I want to sort list b and then print the respective values corresponding to list a.
I cannot use a dictionary because it gives an error that a is not hashable. My desired output is:
x = [[44,66,2,4,77,12], [1,3,45,6,78,9], [2,6,5,88,3,4]]

You can do :
a = [[1,3,45,6,78,9],[2,6,5,88,3,4],[44,66,2,4,77,12]]
b = [4,6,3]
c = sorted([[b[i],a[i]] for i in range(len(a))])
x = [i[1] for i in c]

It can be done on a single line like:
a = [[1,3,45,6,78,9],[2,6,5,88,3,4],[44,66,2,4,77,12]]
b = [4,6,3]
c = [el for _, el in sorted(zip(b, a))]
print(c)
Output:
[[44, 66, 2, 4, 77, 12], [1, 3, 45, 6, 78, 9], [2, 6, 5, 88, 3, 4]]
(If the values in b are not unique, it will sort by first element in the corresponding the values from a)

There is no issue using a dictionary as long as you avoid using any list as a key. In this case, you could use b for keys and a for values. For example,
d = dict(zip(b,a))
print([d[k] for k in sorted(d)])

Related

Python produce alternative numbers list from a list of n numbers

I have a list of n numbers. I want to group them in g groups. Also, I want to reverse elements in every odd group. Finally, I would combine all elements in even and odd groups into a new sublist. First I am giving what answer I am expecting and where I went wrong:
Expected answer:
num = 14
grp = 4
# A list of num natural numbers arranged in group (row) of 4 numbers
lst =
[0,1,2,3,
4,5,6,7,
8,9,10,11,
12,13]
lst =
[[0,1,2,3],
[4,5,6,7],
[8,9,10,11],
[12,13]]
# Reverse elements in odd rows
newlst =
[[0,1,2,3],
[7,6,5,4], # reversed here
[8,9,10,11],
[13,12]] # reversed here
# combine elements in all sublists by their position
# combine first element in all sublists into a new sublist
sollst =
[[0,7,8,13],[1,6,9,12],[2,5,10],[3,4,11]]
My solution:
num = 14
grp = 4
#### print
lst= list(range(0,num,1))
newlst= [lst[i:i+grp:1] for i in range(0,num,grp)]
evnlst = newlst[0::2]
oddlst = newlst[1::2]
newoddlst = [oddlst [i][::-1] for i in range(len(oddlst))]
sollst= evnlst + newoddlst
# This gives [[0, 1, 2, 3], [8, 9, 10, 11], [7, 6, 5, 4], [13, 12]]
from itertools import zip_longest
print([[x for x in t if x is not None] for t in zip_longest(fevngps)])
Present answer:
I reached the one step before the final answer and now I have to combine the lists of different lengths and I am running into an error
TypeError: 'int' object is not subscriptable
One approach:
from itertools import zip_longest
num = 14
grp = 4
lst = list(range(0, num, 1))
newlst = [lst[i:i + grp:1] for i in range(0, num, grp)]
# build new list where the sub-list are reversed if in odd indices
revlst = [lst[::-1] if i % 2 == 1 else lst for i, lst in enumerate(newlst)]
# zip using zip_longest and filter out the None values (the default fill value of zip_longest)
result = [[v for v in vs if v is not None] for vs in zip_longest(*revlst)]
print(result)
Output
[[0, 7, 8, 13], [1, 6, 9, 12], [2, 5, 10], [3, 4, 11]]

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.

List comprehension: Creating new list by adding multiple values in single list

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

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]]

convert n equal length lists to dictionary with unique keys from one list

I have n lists of equal length representing values of database rows. The data is pretty complicated, so i'll present simplified values in the example.
Essentially, I want to map the values of these lists (a,b,c) to a dictionary where the keys are the set of the list (id).
Example lists:
id = [1,1,1,2,2,2,3,3,3]
a = [1,2,3,4,5,6,7,8,9]
b = [10,11,12,13,14,15,16,17,18]
c = [20,21,22,23,24,25,26,27,28]
Needed dictionary output:
{id:[[a],[b],[c]],...}
{'1':[[1,2,3],[10,11,12],[20,21,22]],'2':[[4,5,6],[13,14,15],[23,24,25]],'3':[[7,8,9],[16,17,18],[26,27,28]]}
The dictionary now has a list of lists for the values in the original a,b,c subsetted by the unique values in the id list which is now the dictionary key.
I hope this is clear enough.
Try this:
id = ['1','1','1','2','2','2','3','3','3']
a = [1,2,3,4,5,6,7,8,9]
b = [10,11,12,13,14,15,16,17,18]
c = [20,21,22,23,24,25,26,27,28]
from collections import defaultdict
d = defaultdict(list)
# add as many lists as needed, here n == 3
lsts = [a, b, c]
for ki, kl in zip(id, zip(*lsts)):
d[ki] += [kl]
for k, v in d.items():
# if you don't mind using tuples, simply do this: d[k] = zip(*v)
d[k] = map(list, zip(*v))
The result is exactly as expected according to the question:
d == {'1':[[1,2,3],[10,11,12],[20,21,22]],
'2':[[4,5,6],[13,14,15],[23,24,25]],
'3':[[7,8,9],[16,17,18],[26,27,28]]}
=> True
IDs = [1,1,1,2,2,2,3,3,3]
a = [1,2,3,4,5,6,7,8,9]
b = [10,11,12,13,14,15,16,17,18]
c = [20,21,22,23,24,25,26,27,28]
import itertools
d = {}
for key, group in itertools.groupby(sorted(zip(IDs, a, b, c)), key=lambda x:x[0]):
d[key] = map(list, zip(*group)[1:]) # [1:] to get rid of the ID
print d
OUTPUT:
{1: [[1, 2, 3], [10, 11, 12], [20, 21, 22]],
2: [[4, 5, 6], [13, 14, 15], [23, 24, 25]],
3: [[7, 8, 9], [16, 17, 18], [26, 27, 28]]}

Categories