4

I want to sort column values depending on a row full of int:

cart = [[1, 3, 0, 2], ['olives', 'tomatoes', 'avocado', 'patato']]

and have this

new_cart= [[0, 1, 2, 3], ['avocado', 'olives', 'patato', 'tomatoes' ]]

In other words I want strings to sorted by the integers values which they corresponds:

I found these questions but non of them does what I want:

how to sort 2d array by row in python?

How to sort multidimensional array by column?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Meric Ozcan
  • 678
  • 5
  • 25
  • What is the order rule for the second sub-list? It looks like it is in alphabetical order. Are you pretty much just looking to sort in increasing order? – idjaw Jul 22 '17 at 12:25
  • no integer ordeer let me change it. – Meric Ozcan Jul 22 '17 at 12:25
  • You are sorting the inner lists too? ...Dear? – cs95 Jul 22 '17 at 12:26
  • I edited, as you can see depending on first list with integers, I want to sort strings too as you can see – Meric Ozcan Jul 22 '17 at 12:27
  • As far as I understood your question, you want to sort it like this: a = np.array([[1, 3, 0], ['olives', 'tomatoes', 'avocado']]) a.sort() – Ramesh Kumar Jul 22 '17 at 12:28
  • @RameshKumar You are assuming that numpy is being used here. There is no indication that numpy is being used, and I'm assuming you are using numpy because of the np reference. That is not so easy to decipher. – idjaw Jul 22 '17 at 12:29

2 Answers2

4

A zip-sort-unzip procedure should do the trick:

data = [[1, 3, 0, 2], ['olives', 'tomatoes', 'avocado', 'patato']]
sorted_data = zip(*sorted(zip(data[0], data[1])))
# [(0, 1, 2, 3), ('avocado', 'olives', 'patato', 'tomatoes')]

Or if you want to keep them as lists:

sorted_data = map(list, zip(*sorted(zip(data[0], data[1]))))
# [[0, 1, 2, 3], ['avocado', 'olives', 'patato', 'tomatoes']]

On Python 3.x both zip and map return iterators so if you want to 'bake' them into lists just 'cast' them as such, i.e.:

sorted_data = list(map(list, zip(*sorted(zip(data[0], data[1])))))

NOTE: As suggested by JJoao, you can use argument expansion in the inner zip too instead of explicitly selecting which fields you want to zip from your list, e.g.:

sorted_data = list(map(list, zip(*sorted(zip(*data)))))
zwer
  • 24,943
  • 3
  • 48
  • 66
  • why I cannot print it? this is output – Meric Ozcan Jul 22 '17 at 12:36
  • @RonnieJamesDio - because you're using Python 3.x and its `map` returns an iterator. I'll update the answer. – zwer Jul 22 '17 at 12:37
  • @RonnieJamesDio If the solutions you looked at used `zip`, you probably had your answer all along. Check the documentation on [zip](https://docs.python.org/3.3/library/functions.html#zip). Also, the second part of the solution shows how to end up with a *list*. The *map* object you are looking at is an *iterator*. – idjaw Jul 22 '17 at 12:37
  • I need to end up with a list. – Meric Ozcan Jul 22 '17 at 12:39
  • thank you, I coudnt find a question like mine in the stackoverflow, do you think I can get a vote up :)) – Meric Ozcan Jul 22 '17 at 12:42
  • 1
    @JJoao - fair point, I wanted to keep literal so that the user knows what field its sorted on first. I'll add a note. – zwer Jul 23 '17 at 09:50
  • @zwer: very reasonable decision - expanded version is more didactic. – JJoao Jul 23 '17 at 23:09
0
sorted_data=[ sorted(i) for i in data ]
# [[0, 1, 2, 3], ['avocado', 'olives', 'patato', 'tomatoes']]

This will do the trick. Simple list comprehension .!

rohan
  • 113
  • 1
  • 1
  • 6