Lists are ordered and mutable collections in which the same item can appear multiple times. In other programming languages, lists are sometimes called arrays.

Besides lists, Python has a few other data types to represent collections, with slightly different properties. If you need an ordered but immutable collection, use a Tuples instead of a list. If the items need to be unique, use Sets objects. Etc.

## List basics

A list is delimited by square brackets. It can contain different kinds of objects:

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

### Accessing list items

List items can be accessed by their index. In Python, the first item has index zero:

``````print(aList[0] # first item)
print(aList[1] # second item)
print(aList[2] # third item)
``````
``````>>> 1
>>> -20
>>> hello
``````

Negative numbers can be used to access items backwards:

``````print(aList[-1] # last item)
print(aList[-2] # penultimate etc.)
``````
``````>>> 500
>>> 4.347
``````

### 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"]]
``````

### Operations with lists

Lists can be added using the `+` operator, just like we would do with numbers:

``````print(aList + ['b', 100])
``````
``````>>> [1, -20, 'hello', 4.347, 500, 'b', 100]
``````

Lists can also be multiplied by integers:

``````print(aList * 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.

### Creating copies of a list

Assigning another name to a list doesn’t create a copy, just a new reference to the same list object:

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

It is a common beginner’s mistake to think that assigning a list to a new variable creates another list – it doesn’t! Try to remember this and save yourself a lot of debugging time in the future.

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

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

## List slicing

A slice is a continuous range of items in a list. Here’s how to get a slice from a list:

``````print(aList)
# get from second to fourth items:
print(aList[2:4])
``````
``````>>> [1, -20, 'hello', 4.347, 500]
>>> ['hello', 4.347]
``````

The slicing notation uses list indexes, so use `0` to start from the first item, or simply leave the first index out:

``````# get from first to fourth items:
print(aList[0:4])
# this is the same as:
print(aList[:4])
``````
``````>>> [1, -20, 'hello', 4.347]
>>> [1, -20, 'hello', 4.347]
``````

To finish a slice at the last item, simply leave out the second index:

``````# get from third to last items
print(aList[2:])
``````
``````>>> ['hello', 4.347, 500]
``````

The slicing notation can also be used to create a copy of a list:

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

### String indexes and slices

Indexes and slices also work with strings – after all they are ordered sequences as well.

Characters in a string can be accessed by their index:

``````aString = "the quick brown fox jumps over the lazy dog"
print(aString[2]  # third character)
print(aString[-1] # last character)
``````
``````>>> e
>>> g
``````

Strings can also be sliced, using the same syntax as lists:

``````print(aString[4:20])
``````
``````>>> quick brown fox
``````

### Adding items to a list

New items can be added to a list with the `append` method:

``````aList.append(1234)
print(aList)
``````
``````>>> [1, -20, 'hello', 4.347, 500, 1234]
``````

Similarly, the `extend` method can be used to append a list of items to a another list:

``````aList.extend(['one', 'two', 'three'])
print(aList)
``````
``````>>> [1, -20, 'hello', 4.347, 500, 'one', 'two', 'three']
``````

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

``````aList.insert(3, 'ni!')
print(aList)
``````
``````>>> [1, -20, 'hello', 'ni!', 4.347, 500]
``````

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

``````aList[2:4] = ['one', 'two', 'three']
print(aList)
``````
``````>>> [1, -20, 'one', 'two', 'three', 500]
``````

## Removing list items

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

``````L = ['Doc', 'Grumpy', 'Happy', 'Sleepy', 'Bashful', 'Sneezy', 'Dopey']
del L[0]
print(L)
``````
``````>>> ['Grumpy', 'Happy', 'Sleepy', 'Bashful', 'Sneezy', 'Dopey']
``````

To delete several continuous items, the slice notation can be used:

``````del L[1:4]
print(L)
``````
``````>>> ['Grumpy', 'Sneezy', 'Dopey']
``````

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

``````L.remove('Grumpy')
print(L)
``````
``````>>> ['Sneezy', 'Dopey']
``````

### ‘Popping’ list items

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

``````fruits = ['apple', 'banana', 'grapefruit', 'kiwi', 'melon', 'papaya', 'mango']
print(fruits.pop())
print(fruits)
``````
``````>>> mango
>>> ['apple', 'banana', 'grapefruit', 'kiwi', 'melon', 'papaya']
``````
``````print(fruits.pop())
print(fruits)
``````
``````>>> papaya
>>> ['apple', 'banana', 'grapefruit', 'kiwi', 'melon']
``````

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

``````print(fruits.pop(0))
print(fruits)
``````
``````>>> apple
>>> ['banana', 'grapefruit', 'kiwi', 'melon']
``````

## Ordering lists

Lists items can easily be sorted using the `sort` method:

``````L = ['z', 'a', 'asdas', 100, 2.4, True, [], None]
L.sort()
print(L)
``````
``````>>> [None, True, 2.4, 100, [], 'Asdas', 'a', 'z']
``````

Notice the order in which the different types of Python objects are sorted: `None`, `bool`, `float`, `int`, `list`, `string`.

Here is a list of strings with different kinds of characteres at the starting position, and the sorted output:

``````L2 = ['A', 'abc', ':', '#', '0123', '1', '20', ' ' ]
L2.sort()
print(L2)
``````
``````>>> [' ', '#', '0123', '1', '20', ':', 'A', 'abc']
``````

Lists also have a `reverse` method, to sort items in the inverse order:

``````L3 = ['Barcelona', 'Vienna', 'Rio de Janeiro', 'Sao Paulo', 'Berlin']
L3.reverse()
print(L3)
``````
``````>>> ['Berlin', u'Sao Paulo', 'Rio de Janeiro', 'Vienna', 'Barcelona']
``````

Both `sort` and `reverse` modify the list in-place – this means that the list is modified, but no value is returned:

``````print(L3.sort())
``````
``````>>> None
``````
``````print(L3)
``````
``````>>> ['Barcelona', 'Berlin', 'Rio de Janeiro', 'Sao Paulo', 'Vienna']
``````

This is another common beginner’s mistake: `sort()` and `reverse()` don’t return a value, they modify the lists in place.

In newer Pythons we can use the built-in method `sorted()`, which returns a sorted copy of the given collection, as an alternative to `sort()`:

``````for L in sorted(L3):
print(L, end=" ")
``````
``````>>> Barcelona Berlin Rio de Janeiro Sao Paulo Vienna
``````

A `reversed()` iterator is available as well:

``````for L in reversed(L3):
print(L, end=" ")
``````
``````>>> Vienna Sao Paulo Rio de Janeiro Berlin Barcelona
``````

## Creating number sequences

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

The following command creates a list of numbers, starting from `0` and ending before `10`:

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

Sometimes we need to start a sequence with a number different than zero. In this case, we need to use `range` with two arguments:

``````# from 5 to 10 (doesn't include 10!)
print(range(5, 10))
``````
``````>>> [5, 6, 7, 8, 9]
``````

Finally, we can use a third argument to specify the interval between the numbers in the sequence:

``````# from 1 to 19 (doesn't include 19!)
# in intervals of 3
print(range(1, 19, 3))
``````
``````>>> [1, 4, 7, 10, 13, 16]
``````
Last edited on 23/01/2018