# Python - List

## About

Lists are used to store a collection of different pieces of information in a sequence order of under a single variable name.

A list can be used to implement a Python - Stack.

A list is mutable whereas a tuple is not.

## Articles Related

## Syntax

`list_name = [item_1, item_2]`

- Empty list:

`empty_list = []`

## Constructor

- With range

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

```
>>> list({1,2,3})
{1, 2, 3}
>>> list((1,2,3))
{1, 2, 3}
```

## Operations

### Access by Index

Starting with 0

```
numbers = [1, 2, 3, 4]
numbers[0] == 1
```

### Get the index of an object

```
numbers = [1, 2, 3, 4]
index = numbers.index(2) # Return 1
```

### Set by Index

(starting with 0)

```
numbers = [1, 2, 3, 4]
numbers[0] = 5
# 1 becomes 5
```

### Add

#### a list to a list

```
>>> [1]+[2]
[1, 2]
```

```
myList1 = [1,2,3]
myList2 = [4,5,6]
for i in myList2:
myList1 += [i]
print (myList1)
```

```
[1, 2, 3, 4]
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5, 6]
```

#### an element at the end of the list

A list doesn't have to have a fixed length, they are mutable. Items can be added to the end of a the list.

- One item

`list_name.append(item)`

- N items

```
list = []
list.append(["O"] * 2)
list.append(["N"] * 2)
print list
```

```
[['O', 'O'], ['N', 'N']]
```

#### an element to an index (position)

```
numbers = [4, 3, 2, 1]
three_index = numbers.index(3) # Use index() to find 3
numbers.insert(three_index,3.5)
print numbers
# print [4, 3.5, 3, 2, 1]
```

### Remove

#### Remove an element

- remove will remove the first item from my_list that has a value equal to value

`my_list.remove(value) `

- pop will remove the item at index

`value = my_list.pop(index)`

- del will remove the item at the index, but it won't return it

`del(my_list[1])`

See also filter

#### Remove all elements

```
del list[:]
# python 3
list.clear()
```

### Filter

A list can be filtered through:

- the filter function
- or a comprehension filter

**with the filter function: **

returns a list that contains all the sequence elements that meet a certain condition. Filter is somewhat obsolete because it duplicate the features of list comprehensions

Example:

- Remove all empty string

`filter(None,myList)`

- Remove even elements

```
def is_even(x):
return (x % 2) == 0
filter(is_even, range(10))
```

```
[0, 2, 4, 6, 8]
```

** With a comprehension filter**

- Remove all empty string

```
list = [1, 2, '']
[ x for x in list if x!='']
```

```
[1, 2]
```

### Slice

Slicing (sub-list) returns a list of elements from the position a to the position **before** b.

Syntax:

`myList[a:b:c]`

where in the my_list[a:b:c]:

- a is the first element of the slice. It can be negative (ie -2 means start from the last two elements of list)
- b is the last element of the slice (not include)
- c is the number of element to skip

**Example without skipping:**

```
my_list = [0, 1, 2, 3]
first_three_items = my_list[0:3] # The first three items
first_three_items = my_list[:3] # of
last_two_items = my_list[len(my_list)-2:] # will return the last two items
print my_list
# Prints [0, 1, 2, 3]
print first_three_items
# Prints [0, 1, 2]
print last_two_items
# Prints [2,3]
```

**Example with skipping:**

```
>>> my_list = [0, 1, 2, 3]
>>> my_list[::2]
[0, 2]
>>> my_list[1::2]
[1, 3]
```

## Operator

### Concat

```
m = [1, 2, 3]
n = [4, 5, 6]
print m + n
```

```
[1, 2, 3, 4, 5, 6]
```

### in

```
if 5 not in [1, 2, 3, 4]:
print '5 is not in the list'
```

## Iteration

### List iteration

#### for

```
my_list = [1,3,2]
for number in my_list:
print (number)
```

```
1
3
2
```

After the loop is executed, number remains bound to 2.

#### while

```
my_list = [1,3,2]
i=0
while my_list[i] !=2 :
print (my_list[i])
i = i+1
```

```
1
3
```

### Break and Range

Break with range

```
for number in range(5):
if (number > 3):
break
print number
```

```
0
1
2
3
```

### Reverse iteration

```
for i in reversed([1,2,3]):
print i
```

```
3
2
1
```

### Enumerate through n lists on the same time (zip)

zip create pairs of elements when passed two lists, and will stop at the end of the shorter list.

```
list_a = [1, 4, 5]
list_b = [2, 3]
for a, b in zip(list_a, list_b):
if a > b:
print a, "is bigger than", b
else:
print b, "is bigger than", a
```

```
2 is bigger than 1
4 is bigger than 3
```

### Iterate with the index (enumerate function)

```
choices = ['madelief', 'melissa', 'rixt', 'nico']
for index, item in enumerate(choices):
print index+1, item
```

```
1 madelief
2 melissa
3 rixt
4 nico
```

of

`list(enumerate(choices))`

```
[(0, 'madelief'), (1, 'melissa'), (2, 'rixt'), (3, 'nico')]
```

where you can see that enumerate create tuples with the index and the value

## Comprehension

Comprehensions are a way to loop over elements of a set, list, dictionary, tuple, range, or zip.

### Example

```
>>> ListOfList = [[.25, .75, .1], [-1, 0], [4, 4, 4, 4]]
>>> [sum(x) for x in ListOfList ]
[1.1, -1, 16]
>>> sum([sum(x) for x in ListOfList ])
16.1
```

### Order

A list keep the order of element safe

```
>>> [2*x for x in [2,1,3,4,5] ]
[4, 2, 6, 8, 10]
```

but not a set.

```
>>> [2*x for x in {2,1,3,4,5} ]
[2, 4, 6, 8, 10]
```

### Nested Loop

A double comprehension is a nested for (a for loop in a for loop)

```
>>> [ x*y for x in [1,2,3] for y in [10,20,30] ]
[10, 20, 30, 20, 40, 60, 30, 60, 90]
```

A double comprehension can be use over two lists in order to form a Cartesian product.

```
>>> [ [x,y] for x in ['A','B'] for y in [1,2] ]
[['A', 1], ['A', 2], ['B', 1], ['B', 2]]
```

### Unpacking

```
>>> listoflists = [[1,1],[2,4],[3, 9]]
>>> [y for [x,y] in listoflists]
[1, 4, 9]
```

### Recursive Comprehension

Example: Generation of all combinations of element (in myList) over a variable length (in myLength) :

```
myLength = 3
myList = [0,1]
scalarList = [[i] for i in myList]
count = 1
while count < (myLength):
scalarList = [k+[j] for j in myList for k in scalarList]
count += 1
print(scalarList)
```

```
[[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0], [0, 0, 1], [1, 0, 1], [0, 1, 1], [1, 1, 1]]
```

It's the dynamic version of the following cartesian product:

`[[i,j,k] for i in myList for j in myList for k in myList] `

This function can be use to create all the scalars over a set of vector in order to generate the span (with myList representing the field and myLength the cardinality of the set of vector).

## Aggregate

### Count

- The list

`len([1, 2, 3, 4]) == 4`

- The number of occurrence of an element

```
>>> [1,2,2,3].count(2)
2
```

### Sum

`print sum([1, 2, 3, 4]) `

```
10
```

### Average

```
>>> L = [1, 2, 3, 4]
>>> sum(L)/len(L)
```

## Data Operation

### Sort

The sort method return a “in-place” (mutable) list sorted by increasing numerical/alphabetical order.

```
my_list = [1,3,2]
my_list.sort()
for number in my_list:
print number
```

```
1
2
3
```

Sort can not be used against an element of a dictionary. You have to store the list in a variable before the sort.

### Join (Element concatenation)

Join will concat all the strings element of a list and separate them with a separator.

Syntax:

`StringSeparator.join(mylist)`

```
mylist = ["O"] * 5
print mylist
print " ".join(mylist)
print " - ".join(mylist)
```

```
['O', 'O', 'O', 'O', 'O']
O O O O O
O - O - O - O - O
```

### Flatten a nested list

```
nested = [[1,2], [3,4]]
flat = [a for b in nested for a in b]
```

## Others

### Unpacking

Unpacking: This expression is a convenient way to initialize variables from a list

```
>>> [x,y] = [1, 2]
>>> x
1
>>> y
2
```