23

I have a list of lists where the first element of each nested list is an identifier. I would like to use that identifier to sort the nested lists in alphabetical order.

Example input:

my_list = [
    ['D', 'F', 'E', 'D', 'F', 'D'],
    ['A', 'F', 'E', 'C', 'F', 'E'],
    ['C', 'E', 'E', 'F', 'E', 'E'],
    ['B', 'F', 'E', 'D', 'F', 'F']
]

After the input has been sorted:

my_list = [
    ['A', 'F', 'E', 'C', 'F', 'E'],
    ['B', 'F', 'E', 'D', 'F', 'F'],
    ['C', 'E', 'E', 'F', 'E', 'E'],
    ['D', 'F', 'E', 'D', 'F', 'D']
]

How can one produce this alphabetically sorted list?

3
  • You want to sort the lists based on the first element in the list? Did you try to use a key function for the list sort() method? Commented Jan 11, 2014 at 21:53
  • I have a list that contains non specific amount of elements but every first element of the nested list is an identifier, I would like to use that identifier to sort the list in order Commented Jan 11, 2014 at 21:58
  • 1
    As I note in my response, do not overwrite the built-in constructor, list. stackoverflow.com/questions/21068315/… Commented Jan 11, 2014 at 23:30

6 Answers 6

34

Python automatically sorts lists of lists by the first element. For example:

lol=[[1,2,3],[5,6,7],[0,9,9]]
sorted(lol)
[[0, 9, 9], [1, 2, 3], [5, 6, 7]]
Sign up to request clarification or add additional context in comments.

1 Comment

But the issue is that if the first element is the same, it will continue to sort the list based on the second element, and so on. To keep the order of elements with the same first element, we should use: output_list = sorted(input_list, key = lambda x: x[0])
28

You want to use .sort() or sorted:

>>> t = [['D', 'F', 'E', 'D', 'F', 'D'], ['A', 'F', 'E', 'C', 'F', 'E'], ['C', 'E', 'E', 'F', 'E', 'E'], ['B', 'F', 'E', 'D', 'F', 'F']]
>>> t.sort(key=lambda x: x[0])  # changes the list in-place (and returns None)
>>> t
[['A', 'F', 'E', 'C', 'F', 'E'], ['B', 'F', 'E', 'D', 'F', 'F'], ['C', 'E', 'E', 'F', 'E', 'E'], ['D', 'F', 'E', 'D', 'F', 'D']]

Also note that your list needs commas between its elements. Here is the result for sorted:

>>> sorted(t)  # does not change the list but returns the sorted list
[['A', 'F', 'E', 'C', 'F', 'E'], ['B', 'F', 'E', 'D', 'F', 'F'], ['C', 'E', 'E', 'F', 'E', 'E'], ['D', 'F', 'E', 'D', 'F', 'D']]

As you can see, the latter example sorts the lists without any key argument. The former example can as well; but you mention that only the first element is a unique identifier, so there is no way to tell what the secondary criteria might be for sorting the list beyond the first element.

Comments

7

Essentially the same as the others but uses operator.itemgetter(),

from operator import itemgetter
first_item = itemgetter(0)
new_list = sorted(original_list, key = first_item)

Comments

5

lists.sort(key = lambda x: x[0]) Make sure you put commas between each list in the larger list.

Comments

3

You shouldn't overwrite the builtin list constructor, list, use another name instead like this:

>>> a_list = [['D', 'F', 'E', 'D', 'F', 'D'],['A', 'F', 'E', 'C', 'F', 'E'],['C', 'E', 'E', 'F', 'E', 'E'],['B', 'F', 'E', 'D', 'F', 'F']]

To sort the list in place, use the list.sort method:

>>> a_list.sort()

>>> a_list
[['A', 'F', 'E', 'C', 'F', 'E'], ['B', 'F', 'E', 'D', 'F', 'F'], ['C', 'E', 'E', 'F', 'E', 'E'], ['D', 'F', 'E', 'D', 'F', 'D']]

The built-in function, sorted, returns a new list, which is something you didn't seem to want to do. It returns a new list, which if you no longer need the old list would waste space in memory.

Python automatically sorts on the first element. It then automatically sorts on the second, third, and so on. Using lambda as others suggested would mean you would only sort on the first element, and the following elements would be ignored.

>>> a_list = [['b', 'f'],['b', 'e'],['b', 'd'],['a', 'c'],['a', 'b'],['a', 'a'],]
>>> a_list.sort(lambda x,y : cmp(x[0], y[0]))
>>> a_list
[['a', 'c'], ['a', 'b'], ['a', 'a'], ['b', 'f'], ['b', 'e'], ['b', 'd']]

This is why the sort is described as a stable sort

>>> help(list.sort)
Help on method_descriptor:

sort(...)
    L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;
    cmp(x, y) -> -1, 0, 1

Comments

0

For those who have a list of list of strings with varied case, e.g.:

var = [['ant', 'bat'], ['Frog','Bat'], ['Bat','Ant']]

And wish to sort by the nth element in the list, then one of the following will work:

n_elem = 0  # specify nth element to sort by

# Basic case handling with .lower()
var.sort(key=lambda l: l[n_elem].lower())
sorted(var, key=lambda l: l[n_elem].lower())

# More robust case handling with .casefold()
var.sort(key=lambda l: l[n_elem].casefold())
sorted(var, key=lambda l: l[n_elem].casefold())

# Avoiding undefined sorting orders when lowercase strings are equal (most robust)
var.sort(key=lambda l: (l[n_elem].casefold(), l))
sorted(var, key=lambda l: (l[n_elem].casefold(), l))

Example output:

[['ant', 'bat'], ['Bat', 'Ant'], ['Frog', 'Bat']]

Note:

  • .sort() will modify the list in-place and return None
  • sorted() will return a new, sorted list

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.