Lists are ordered and mutable collections of non-unique items.

In other programming languages, lists are sometimes called arrays.

## List basics

Lists are delimited by square brackets and can contain different types of items:

``````>>> list1 = [1, -20, "hello", 4.347, 500]
``````

### Accessing list items

List items can be accessed by their index or position. In Python and most other programming languages, the first item has index `0` (zero):

``````>>> list1[0] # first item
``````
``````1
``````
``````>>> list1[2] # third item
``````
``````hello
``````

Negative numbers can be used to access items backwards:

``````>>> list1[-1] # last item
``````
``````500
``````

### Nested lists

Lists can contain other lists, which can contain other lists, and so on. This is known as nested lists:

``````>>> list2 = [1, 2, 3, ["a", "b", "c"]]
>>> list3 = [1, 2, 3, ["a", ["A", "B"], "b", [], "c"]]
``````

Items in nested lists can be accessed by ‘chaining’ the indexes of the parent lists and the item index:

``````>>> list3[-1][1][0]
``````
``````'A'
``````

### Operations with lists

Lists can be added using the `+` operator. The result is a new list with the items of the lists concatenated in the given order.

``````>>> list1 + ['b', 100] + ['abcdef']
``````
``````[1, -20, 'hello', 4.347, 500, 'b', 100, 'abcdef']
``````

Lists can also be multiplied by integers. The result is equivalent to adding the list to itself `n` times:

``````>>> list1 * 3
``````
``````[1, -20, 'hello', 4.347, 500, 1, -20, 'hello', 4.347, 500, 1, -20, 'hello', 4.347, 500]
``````

Subtraction and division operations are not supported with lists.

### Making copies of a list

Assigning a list to a new variable does not create another list, just a new reference to the same list object:

``````>>> anotherList = list1
>>> anotherList.append(-9999) # add an element to the list
>>> list1
``````
``````[1, -20, 'asdsd', 4.347, 500, -9999]
``````

We’ve added an item to `anotherList`, and it appeared when we printed `list1`. It makes sense once we understand that both variable names point to the same list.

It is a common beginner’s mistake to expect that assigning a list to a new variable creates a copy of the list. It does not. Try to remember this in the future if your lists start to misbehave misteriously.

There are different ways to create a copy of a list. One of them is using the built-in function `list()`:

``````>>> aCopy = list(list1)
>>> aCopy.append(9999)
>>> aCopy
``````
``````[1, -20, 'hello', 4.347, 500, -9999, 9999]
``````
``````>>> list1
``````
``````[1, -20, 'hello', 4.347, 500, -9999]
``````

Another way of making a copy of a list is by creating a slice of the whole list (see the next section).

## List slicing

A slice is a continuous range of items in a list. Slicing a list returns a new list.

A slice is defined using start and end indexes separated by a colon:

``````>>> list1 = [1, -20, 'hello', 4.347, 500, 'abcdefg']
>>> list1[2:4] # get a slice from 3nd to 5th items
``````
``````['hello', 4.347]
``````

The item at the start index is included in the slice, the one at the end index is not.

To start a slice before the first item, use `0` or simply leave out the first index:

``````>>> list1[:4] # same as: list1[0:4]
``````
``````[1, -20, 'hello', 4.347]
``````

To finish a slice after the last list item, leave out the second index:

``````>>> list1[2:]
``````
``````['hello', 4.347, 500, 'abcdefg']]
``````

The slicing notation can be used to create a copy of a list – just leave out start and end values to make a slice that includes all items:

``````>>> newList = list1[:]
>>> newList.append('spam')
``````
``````[1, -20, 'hello', 4.347, 500, 'abcdefg', 'spam']
``````
``````>>> list1
``````
``````[1, -20, 'hello', 4.347, 500, 'abcdefg']
``````

## Adding items to a list

Use the `append` method to add new items to a list:

``````>>> list1 = ['spam', 'eggs']
>>> list1.append('bacon')
>>> list1
``````
``````['spam', 'eggs', 'bacon']
``````

Similarly, use the `extend` method to append a list of items to a another list:

``````>>> list1.extend(['spam', 'spam'])
>>> list1
``````
``````['spam', 'eggs', 'bacon', 'spam', 'spam']
``````

The `insert` method allows you to insert an item at a specific position using a list index:

``````>>> list1.insert(3, 'sausages')
>>> list1
``````
``````['spam', 'eggs', 'bacon', 'sausages', 'spam', 'spam']
``````

Finally, the slice notation can be used to replace a section of a list with another list:

``````>>> list1[1:4] = ['spam', 'spam', 'spam']
>>> list1
``````
``````['spam', 'spam', 'spam', 'spam', 'spam', 'spam']
``````

## Removing items from a list

List items can be removed using the `del` command and the item’s index:

``````>>> L = ['Graham', 'Eric', 'Terry', 'John', 'Terry', 'Michael']
>>> del L[-1]
>>> L
``````
``````['Graham', 'Eric', 'Terry', 'John', 'Terry']
``````

If you don’t know the index of item, you can use the `remove` method and refer to the item itself:

``````L.remove('Terry')
>>> L
``````
``````['Graham', 'Eric', 'John', 'Terry']
``````

If an item appears multiple times in the list, only the first one is removed.

The slice notation can be used to remove several continuous items at once:

``````>>> del L[1:3]
>>> L
``````
``````['Graham', 'Terry']
``````

### ‘Popping’ items

The `pop` method removes an item from a list and at the same time returns it. This is useful to make lists behave like stacks.

Here we take the last item from the stack:

``````>>> myList = ['parrot', 'ant', 'fish', 'goat', 'cat', 'rabbit', 'frog']
>>> myList.pop()
``````
``````frog
``````

If we ask to see list again, we can see that the last item is gone:

``````>>> myList
``````
``````['parrot', 'ant', 'fish', 'goat', 'cat', 'rabbit']
``````

The `pop` method can also take a index – this allows us to take out an item which is not the last one:

``````>>> myList.pop(0) # take the first item
``````
``````'parrot'
``````
``````>>> myList
``````
``````['ant', 'fish', 'goat', 'cat', 'rabbit']
``````

## Sorting lists

List items can be sorted using the `sort` method.

Sorting is straightforward when all items in a list are of the same type.

For example, if all items are strings, the list will be sorted alphabetically:

``````>>> stringsList = ['parrot', 'ant', 'fish', 'goat', 'cat', 'rabbit', 'frog']
>>> stringsList.sort()
>>> stringsList
``````
``````['ant', 'cat', 'fish', 'frog', 'goat', 'parrot', 'rabbit']
``````

If all items are numbers, they will be sorted numerically in ascending order:

``````>>> numbersList = [7, 3.1416, 13, -273.15, 2.718, 0, 356.25]
>>> numbersList.sort()
>>> numbersList
``````
``````[-273.15, 0, 2.718, 3.1416, 7, 13, 356.25]
``````

### Reversing a list

The `reverse` method can be used to revert the order of the items in a list:

``````>>> aList = ['one', 'two', 'three', 'four', 'five']
>>> aList.reverse()
>>> aList
``````
``````['five', 'four', 'three', 'two', 'one']
``````

The `sort` method also has a `reverse` keyword to invert the default sorting order from ascending to descending:

``````# sort list items in reverse alphabetical order
>>> aList.sort(reverse=True)
>>> aList
``````
``````['two', 'three', 'one', 'four', 'five']
``````

### Sorting lists with mixed object types

If a list contains different types of objects, we need to define a parameter for comparison. A straight sort with different object types is like comparing apples to oranges, and will not work in Python 3:

``````>>> mixedList = ['z', 'a', 'abcdefg', 100, 2.4, True, [], None]
>>> mixedList.sort()
``````
``````Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: '<' not supported between instances of 'int' and 'str'
``````

How does a number compare to a string? How do numbers and strings compare to lists, boolean values, or to `None`? There are different ways to answer these questions depending on the context and on the desired result.

Sorting mixed lists was supported in Python 2, but only thanks to many assumptions about comparisons between types. Python 3 requires us to be explicit about the comparison criteria used for sorting.

The example script shows how to sort a list containing different data types using a key function:

``````# create a flat list containing strings and numbers
myList = ['Graham', 'Eric', 'Terry', 'John', 'Terry', 'Michael']
myList += ['parrot', 'ant', 'fish', 'goat', 'cat', 'rabbit', 'frog']
myList += [7, 3.1416, 13, -273.15, 2.718, 0, 356.25]
myList += ['3M', '7UP', '7-Eleven']

# define a key function
def sorter(item):
'''Convert a list item into a key for sorting.'''
return str(item).lower()

# sort the list using the key function
myList.sort(key=sorter)

print(myList)
``````
``````[-273.15, 0, 13, 2.718, 3.1416, 356.25, '3M', 7, '7-Eleven', '7UP', 'ant', 'cat', 'Eric', 'fish', 'frog', 'goat', 'Graham', 'John', 'Michael', 'parrot', 'rabbit', 'Terry', 'Terry']
``````

### Sorting lists of values with itemgetter

One of the many uses for lists is storing groups of values. As an example, let’s imagine that we have some very basic information about a group of people as a list of values: a tuple with first name, last name and birth year:

``````persons = [
# first name, last name, birth year
('Graham', 'Chapman', 1941),
('Eric', 'Idle', 1943),
('Terry', 'Gilliam', 1940),
('Terry', 'Jones', 1942),
('John', 'Cleese', 1939),
('Michael', 'Palin', 1943),
]
``````

Using what we’ve learned in the previous section, we could write separate key functions to sort this list based on different index values:

``````def lastNameSorter(item):
return item[1]

def birthYearSorter(item):
return item[2]

persons.sort(key=lastNameSorter) # option: key=birthYearSorter
print(persons)
``````
``````[('Graham', 'Chapman', 1941), ('John', 'Cleese', 1939), ('Terry', 'Gilliam', 1940), ('Eric', 'Idle', 1943), ('Terry', 'Jones', 1942), ('Michael', 'Palin', 1943)]
``````

Notice how the functions repeat a ‘get item’ pattern. This is so common that Python provides a convenience `itemgetter` function in the `operator` module (we’ll learn more about modules later):

``````from operator import itemgetter
persons.sort(key=itemgetter(2)) # sort by year
print(persons)
``````
``````[('John', 'Cleese', 1939), ('Terry', 'Gilliam', 1940), ('Graham', 'Chapman', 1941), ('Terry', 'Jones', 1942), ('Eric', 'Idle', 1943), ('Michael', 'Palin', 1943)]
``````

Using `itemgetter` it is also possible to define multiple levels of sorting. For example, sorting by first name (1st item) and last name (2nd item):

``````persons.sort(key=itemgetter(0, 1))
print(persons)
``````
``````[('Eric', 'Idle', 1943), ('Graham', 'Chapman', 1941), ('John', 'Cleese', 1939), ('Michael', 'Palin', 1943), ('Terry', 'Gilliam', 1940), ('Terry', 'Jones', 1942)]
``````

## Using the sorted() and reversed() built-ins

In addition to the `list.sort` method, Python also offers a `sorted()` built-in function which builds a new sorted list from a collection (not just a list). Using `sorted(list)` is often more convenient than using `list.sort()`.

Here’s an example of `sorted()` in use. Notice that the original list is not modified:

``````>>> flags = ['Foxtrot', 'Bravo', 'Whisky', 'Tango', 'Charlie', 'Echo']
>>> sorted(flags)
``````
``````['Bravo', 'Charlie', 'Echo', 'Foxtrot', 'Tango', 'Whisky']
``````
``````>>> flags
``````
``````['Foxtrot', 'Bravo', 'Whisky', 'Tango', 'Charlie', 'Echo']
``````

The `reversed()` built-in function works similarly, but returns an `iterator` object instead of a new list.

Both `sorted()` and `reversed()` are often used to loop over a list of items:

``````>>> for flag in reversed(flags):
...     flag
``````
``````'Echo'
'Charlie'
'Tango'
'Whisky'
'Bravo'
'Foxtrot'
``````

## Creating number sequences

Sequential lists of numbers can be created dynamically using the `range` built-in function.

Here’s how we create a list of numbers, starting at `0` and ending before `10`:

``````>>> list(range(10))
``````
``````[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
``````

In Python 2, `range` returns a list. In Python 3, it returns an iterator object – which we can convert into a list using the `list()` built-in function.

<!–

Conditional expressions

–>

Last edited on 08/12/2018