user3798245
user3798245

Reputation: 51

How can I sort 2 lists of lists by column?

I have 2 list of lists:

a=[['abc',2, 'cde'],
   ['xyz',5, 'fgh']]


b=[['abc', 'lmn', 2],
   ['xyz','opq',5]]

i would like to get result list of lists like that:

result = [['abc',2, 'cde'],
          ['abc', 'lmn', 2],
          ['xyz',5, 'fgh'],
          ['xyz','opq',5] ]

where the list result is ordered by 2nd column of the first list of lists and by third column of the second list of lists.

I cheched here: Python: sorting a list by "column" this code:

sorted(a, key=lambda x: x[0])

but it is for only one list of lists.

Upvotes: 0

Views: 88

Answers (4)

Grasshopper
Grasshopper

Reputation: 436

Use the following simple code -

templist = []
for i in range(len(a)):
    templist.append(a[i])
    templist.append(b[i])
print(templist)

Upvotes: 0

inspectorG4dget
inspectorG4dget

Reputation: 113915

I see two interpretations of your question:

  1. Sort a, then sort b, then interleave the sublists together:

In [14]: a=[['abc',2, 'cde'],
   ....:    ['xyz',5, 'fgh']]

In [15]: b=[['abc', 'lmn', 2],
   ....:    ['xyz','opq',5]]

In [16]: a.sort(key=operator.itemgetter(1))

In [17]: b.sort(key=operator.itemgetter(2))

In [18]: result = [list(i) for i in zip(a,b)]

In [19]: result
Out[19]: 
[[['abc', 2, 'cde'], ['abc', 'lmn', 2]],
 [['xyz', 5, 'fgh'], ['xyz', 'opq', 5]]]
  1. Modify a and b, add them together, sort the resultant, and unmodify the result:

In [20]: a=[['abc',2, 'cde'], ['xyz',5, 'fgh']]

In [21]: b=[['abc', 'lmn', 2],
   ['xyz','opq',5]]

In [22]: a = [[0]+i for i in a]

In [23]: b = [[1]+i for i in b]

In [24]: result = sorted(a+b, key=lambda s: s[3] if s[0] else s[2])

In [25]: result
Out[25]: 
[[0, 'abc', 2, 'cde'],
 [1, 'abc', 'lmn', 2],
 [0, 'xyz', 5, 'fgh'],
 [1, 'xyz', 'opq', 5]]

In [26]: result = [s[1:] for s in sorted(a+b, key=lambda s: s[3] if s[0] else s[2])]

In [27]: result
Out[27]: [['abc', 2, 'cde'], ['abc', 'lmn', 2], ['xyz', 5, 'fgh'], ['xyz', 'opq', 5]]

Upvotes: 0

DSM
DSM

Reputation: 353019

One way -- not necessarily the most elegant, but effective -- is to add information about which list (a or b) a given row comes from to an intermediate structure, so we know whether to use col #1 or #2. For example:

decorated = [(i,row) for i,lol in enumerate([a,b]) for row in lol]
new_lol = sorted(decorated, key=lambda x: x[1][1 if x[0]==0 else 2])
new_lol = [x[1] for x in new_lol]

which gives

>>> new_lol
[['abc', 2, 'cde'], ['abc', 'lmn', 2], ['xyz', 5, 'fgh'], ['xyz', 'opq', 5]]

and which works because we have

>>> decorated
[(0, ['abc', 2, 'cde']), (0, ['xyz', 5, 'fgh']), (1, ['abc', 'lmn', 2]), (1, ['xyz', 'opq', 5])]

as our intermediate structure.

Upvotes: 1

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 798566

Decorate, sort, undecorate.

>>> [z[1] for z in sorted([(x[1], x) for x in a] + [(y[2], y) for y in b], key=operator.itemgetter(0))]
[['abc', 2, 'cde'], ['abc', 'lmn', 2], ['xyz', 5, 'fgh'], ['xyz', 'opq', 5]]

Upvotes: 0

Related Questions