Question

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.

Was it helpful?

Solution

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

OTHER TIPS

I would start by converting your three lists to a single list of three-tuples:

newList = zip(*lst)

This would give you:

[("1", "some text", "some text"), ...]

You will need to define a sorting function to encode your RZ rules, but then it is easy to sort:

def sortFunc(item):
    # example, not sure what you need
    return item[2].lower().count("rz") 

sorted(newList, key=sortFunc)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top