Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting columns in Python 3.3 nested list by partial comparison

I’m trying to sort columns in nested list like that:

lst = [["1", "2", "3", "4"],
       ["some text 1", "some text 2", "some text 3", "some text 4"],
       ["some text", "some text to analyze with RZstring", "some RZ-text to analyze", "some text to analyze with no rz-string and no textRZ"]]

according to the presence of case-sensitive 'RZ' prefix in strings of 3-rd nested list (those with RZ should be at the bottom):

lst = [["1", "4", "2", "3"],
       ["some text 1", "some text 4", "some text 2", "some text 3"],
       ["some text", "some text to analyze with no rz-string and no textRZ", "some text to analyze with RZstring", "some RZ-text to analyze"]]

I feel there should be some nice and easy way with itemgetter or lambda-function, but see no obvious solution.

like image 499
night_bat Avatar asked Apr 12 '26 01:04

night_bat


1 Answers

You seem to be mixing two problems here. First is sorting a nested list like that, and the second is how to sort according to those RZ things.

You can do the former by transposing the multidimensional array first so that items that belong together are actually in the same sublist. And then you can just sort according to your sort function on the 3rd list item.

>>> list(zip(*sorted(zip(*lst), key=lambda x: x[2])))
[('3', '1', '2', '4'), ('some text 3', 'some text 1', 'some text 2', 'some text 4'), ('some RZ-text to analyze', 'some text', 'some text to analyze with RZstring', 'some text to analyze with no rz-string and no textRZ')]

For your second problem however, I don’t really understand what this sorting is based on. If it was the prefix before RZ, then the latter two items would still be reversed, or not?


Based on your updated specification in the comments, you could use a regular expression to check if RZ occurs with a word boundary in front (\b) and add that fact in from of the sort-key:

>>> import re
>>> list(zip(*sorted(zip(*lst), key=lambda x: (re.search(r'\bRZ', x[2]) != None, x[2]))))
[('1', '4', '3', '2'), ('some text 1', 'some text 4', 'some text 3', 'some text 2'), ('some text', 'some text to analyze with no rz-string and no textRZ', 'some RZ-text to analyze', 'some text to analyze with RZstring')]
like image 174
poke Avatar answered Apr 13 '26 15:04

poke