# List

List is one of the **compound** data types in Python. Lists can group together elements. &#x20;

A list is written as a **comma-separated**  `,` elements (values or items) between **square brackets** `[]`. Lists might contain elements of different types, but usually the elements all have the same type.

```python
# empty list
my_list = []

# list of integers
my_list = [1, 2, 3, 4]

# list of strings
my_list = ['Krakow', 'Warsaw', 'Poznan', 'Wroclaw']

# list with mixed datatypes
my_list = ['Krakow', 2, 3.86, True]
```

Python lists are:

* Lists can be empty
* Lists can have any elements
* Lists are ordered
* List elements can be accessed by index
* Lists can be nested to any arbitrary depth
* Lists are mutable, i.e. they can be modified after they are created

## Lists can be empty

An empty list can be created by assigning empty **square brackets** to an identifier.

```python
# empty list
my_list = []
```

## Lists can have any elements

Lists can contain a single datatype or a mixture of datatypes.

```python
# list of integers
my_list = [1, 2, 3, 4]

# list of floats
my_list = [1.2, 2.4, 3.6, 4.8]

# list of strings
my_cities = ['Krakow', 'Warsaw', 'Poznan', 'Wroclaw']

# list with mixed datatypes
my_list = ['Krakow', 2, 3.86, True]
```

## Lists are ordered

The order of elements in a list is important. Two lists are not the same if the elements within a list are same but in a different order.

```python
list_01 = [1, 2, 3, 4]
list_02 = [4, 3, 2, 1]
```

These two lists have the same elements but in **different order**

{% tabs %}
{% tab title="Code" %}

```python
list_01 == list_02
```

{% endtab %}

{% tab title="Output" %}

```python
False
```

{% endtab %}
{% endtabs %}

You can use is keyword too.

{% tabs %}
{% tab title="Code" %}

```python
list_01 is list_02
```

{% endtab %}

{% tab title="Output" %}

```python
False
```

{% endtab %}
{% endtabs %}

## List elements can be accessed by index

You can use the index operator of **square brackets**`[]` to access an element in a list. In Python, index starts from 0.&#x20;

Index number should be an integer, otherwise it raises `TypeError`. Python will raise an `IndexError` if the index element is outside of the length of the list minus one.

```python
my_cities = ['Krakow', 'Warsaw', 'Poznan', 'Wroclaw']
```

### Positive Indexing

The indices for the elements are as follow:

![Positive Index](/files/-M2T2A8SnK22uIU7GjFP)

You can access each element by writing the name of the **`list`** followed by **square brackets** `[]` and **`index number`**&#x6F;f the element.

```python
my_cities[0]
# OUTPUT:
'Krakow'

my_cities[3]
# OUTPUT:
'Wroclaw'
```

### Negative indexing

Python allows negative indexing for elements in a list. Negative index counts from the end of the list. **-1** is the index of last element, **-2** is the index of second from last element, so on.

![Negative Index](/files/-M2TL3LGD8zUXxdcvgZD)

You can access elements in a list using negative index.&#x20;

```python
my_cities[-1]
# OUTPUT:
'Wroclaw'

my_cities[-3]
# OUTPUT:
'Warsaw'
```

### List slicing in Python

Slicing of a list needs two indices: `start index` and `end index` separated by a **colon `:`**

All slice operations return a new list containing the requested elements. This means that the following slice returns a [shallow copy](https://docs.python.org/3/library/copy.html#shallow-vs-deep-copy) of the list.

```python
my_list = [2, 3, 4, 5, 5, 7, 8, 1,5, 6, 2, 9, 0]
```

You create a new list using slice operations. **Square brackets** `[]` with **colon** `:` will select all elements in the list and assign it to a new list

```python
new_list = my_list[:]
```

Let's compare `my_list` with `new_list`

{% tabs %}
{% tab title="== comparison" %}

```python
my_list == new_list
```

{% endtab %}

{% tab title="Output 1" %}

```python
True
```

{% endtab %}

{% tab title="is keyword comparison" %}

```python
my_list is new_list
```

{% endtab %}

{% tab title="Output 2" %}

```python
False
```

{% endtab %}
{% endtabs %}

While comparing `new_list` with `my_list` with `==`, Python returns `True` but comparison with Python keyword `is` returns `False`. `==` compares the orders of elements in the`my_list` and `new_list`but Python`is` keyword is referencing memory locations of the `my_list` and `new_list` which are different and returns `False.`

#### Slicing to select/filter elements

Let's say you want to get the 2nd to 7th elements. Our start index is 1 and end index is 7 (End index returns the index before index 7, so in this case until index 6).

{% tabs %}
{% tab title="Code" %}

```python
# value 2nd to 7th
start_index = 1
end_index = 7
my_list[start_index:end_index]
my_list[1:7] # you can write it this way too.
```

{% endtab %}

{% tab title="Output" %}

```python
[3, 4, 5, 5, 7, 8]
```

{% endtab %}
{% endtabs %}

Lists usually start counting from left to right. Empty start index location means select/filter elements from the start.

{% tabs %}
{% tab title="Code" %}

```python
# value beginning to 6th
my_list[:6]
```

{% endtab %}

{% tab title="Output" %}

```python
[2, 3, 4, 5, 5, 7]
```

{% endtab %}
{% endtabs %}

Empty end index location means select/filter the elements from start index to the last element in the list.&#x20;

{% tabs %}
{% tab title="Code" %}

```python
# value 6th to the end
my_list[5:]
```

{% endtab %}

{% tab title="Output" %}

```python
[7, 8, 1, 5, 6, 2, 9, 0]
```

{% endtab %}
{% endtabs %}

You can use a mixture of index and negative index together. For example; let's select 2nd element from start until 3rd element from the end. \
2nd element has index of **1** (Python starts zero index) and 3rd element from end has index of **-2**, end index returns the (index - 1), meaning index is bigger by one number.

{% tabs %}
{% tab title="Code" %}

```python
# value 2nd from start until 2nd from the end
my_list[1:-2]
```

{% endtab %}

{% tab title="Output" %}

```python
[3, 4, 5, 5, 7, 8, 1, 5, 6, 2]
```

{% endtab %}
{% endtabs %}

### Stride

You can specify a stride—either positive or negative. Stride is added to the square bracket as a **second colon `:`**, the stride form will be `[start_index : end_index : step]`. Step control defines how many elements to skip before selecting next element.&#x20;

{% tabs %}
{% tab title="Code" %}

```python
my_list = [2, 3, 4, 5, 5, 7, 8, 1,5, 6, 2, 9, 0]

my_list[1:7:2] # this will select elements 2nd to 7th every two steps
```

{% endtab %}

{% tab title="Output" %}

```python
[3, 5, 7]
```

{% endtab %}
{% endtabs %}

### List reverse

Python lets you to easily reverse lists

{% tabs %}
{% tab title="Code" %}

```python
my_list = [2, 3, 4, 5, 5, 7, 8, 1,5, 6, 2, 9, 0]

my_list[::-1]
```

{% endtab %}

{% tab title="Output" %}

```python
[0, 9, 2, 6, 5, 1, 8, 7, 5, 5, 4, 3, 2]
```

{% endtab %}
{% endtabs %}

## Lists can be nested

A list can contain sublists, which in turn can contain sublists themselves.&#x20;

![A list of lists with their indice](/files/-M2m0eQDwB6Kf-aiHXfb)

Each element in list or its sublists can be accessed with element index.

{% tabs %}
{% tab title="Code" %}

```python
my_list = ['a', ['b', 'c', 'd'], 'e', [['f', 'g'], 'h'], 'i', 'j']

my_list[3]
```

{% endtab %}

{% tab title="Output" %}

```python
# Returns all sublists in the index number 3
[['f', 'g'], 'h']
```

{% endtab %}
{% endtabs %}

Each sublist adds another square bracket to access its elements. `my_list[3][1]` returns index 3 of main list and an element at index 1 of the sublist

Simply append another square bracket. All operation of slicing can also be performed on the second square bracket, etc.

{% tabs %}
{% tab title="Code" %}

```python
my_list = ['a', ['b', 'c', 'd'], 'e', [['f', 'g'], 'h'], 'i', 'j']

my_list[3][1]
```

{% endtab %}

{% tab title="Output" %}

```python
# It return index 3 of main list and elements at index 1 of the sublist
'h'
```

{% endtab %}
{% endtabs %}

## Lists are mutable

Elements with a list can be deleted, shifted, updated or modified after the list has been created. You can change each element of a list or append new elements to a list.&#x20;

You can use assignment operator (`=`) to change an item or a range of items.

### **Updating a single element**

A single value in a list can be replaced by indexing and assignment operator.

{% tabs %}
{% tab title="Code Index" %}

```python
my_list = [2, 3, 4, 5, 5, 7, 8, 1,5, 6, 2, 9, 0]

my_list[5] = 2020
```

{% endtab %}

{% tab title="Output 1" %}

```python
[2, 3, 4, 5, 5, 2020, 8, 1, 5, 6, 2, 9, 0]
```

{% endtab %}

{% tab title="Code Negative Index" %}

```python
my_list = [2, 3, 4, 5, 5, 7, 8, 1,5, 6, 2, 9, 0]

my_list[-3] = 2020
```

{% endtab %}

{% tab title="Output 2" %}

```python
[2, 3, 4, 5, 5, 7, 8, 1, 5, 6, 2020, 9, 0]
```

{% endtab %}
{% endtabs %}

### Updating multiple elements

Multiple elements can be update by specifying the elements index

{% tabs %}
{% tab title="Code" %}

```python
my_list = [2, 3, 4, 5, 5, 7, 8, 1,5, 6, 2, 9, 0]

my_list[5:8] = [2018, 2019, 2020] 
```

{% endtab %}

{% tab title="Output" %}

```python
[2, 3, 4, 5, 5, 2018, 2019, 2020, 5, 6, 2, 9, 0]
```

{% endtab %}
{% endtabs %}

### **Deleting a single element**

An element or elements can be deleted using `del` keyword.

{% tabs %}
{% tab title="Code: Delete an element" %}

```python
my_list = [2, 3, 4, 5, 5, 7, 8, 1,5, 6, 2, 9, 0]

del my_list[5]
```

{% endtab %}

{% tab title="Output 1" %}

```python
[2, 3, 4, 5, 5, 8, 1, 5, 6, 2, 9, 0]
```

{% endtab %}

{% tab title="Code: Delete elements" %}

```python
my_list = [2, 3, 4, 5, 5, 7, 8, 1,5, 6, 2, 9, 0]

del my_list[3:6]
```

{% endtab %}

{% tab title="Output 2" %}

```python
[2, 3, 4, 8, 1, 5, 6, 2, 9, 0]
```

{% endtab %}
{% endtabs %}

First example deletes element `[7]`, second example deletes three elements `[5, 5, 7]`.

### **Prepending or appending elements to a list**&#x20;

An element or elements can be added to the start or end of a list using the `+` operator. This is also called **concatenation**.

{% tabs %}
{% tab title="Prepend" %}

```python
my_list = [2, 3, 4, 5, 5, 7, 8, 1,5, 6, 2, 9, 0]

[343, 564] + my_list

# OUTPUT
[343, 564, 2, 3, 4, 5, 5, 7, 8, 1, 5, 6, 2, 9, 0]
```

{% endtab %}

{% tab title="Append" %}

```python
my_list = [2, 3, 4, 5, 5, 7, 8, 1,5, 6, 2, 9, 0]

my_list + [343, 564]

# OUTPUT
[2, 3, 4, 5, 5, 7, 8, 1, 5, 6, 2, 9, 0, 343, 564]
```

{% endtab %}
{% endtabs %}

If you want to add a single element, we have to wrap it in square brackets `[]`. Otherwise, Python raises a `TypeError`.

{% tabs %}
{% tab title="Code" %}

```python
my_list = [2, 3, 4, 5, 5, 7, 8, 1,5, 6, 2, 9, 0]

my_list = 22 + my_list
```

{% endtab %}

{% tab title="Output" %}

```python
TypeError       Traceback (most recent call last)
<ipython-input-11-57d83415c5aa> in <module>()
      1 my_list = [2, 3, 4, 5, 5, 7, 8, 1,5, 6, 2, 9, 0]
      2 
----> 3 my_list = 22 + my_list

TypeError: unsupported operand type(s) for +: 'int' and 'list'
```

{% endtab %}
{% endtabs %}

The `=` assignment operator can be used to save the prepending or appending elements.&#x20;

{% tabs %}
{% tab title="Prepend" %}

```python
# Elements addition
my_list = [2, 3, 4, 5, 5, 7, 8, 1,5, 6, 2, 9, 0]

my_list = [343, 564] + my_list

print(my_list)

#OUTPUT
[343, 564, 2, 3, 4, 5, 5, 7, 8, 1, 5, 6, 2, 9, 0]
```

{% endtab %}

{% tab title="Append" %}

```python
# Elements addition
my_list = [2, 3, 4, 5, 5, 7, 8, 1,5, 6, 2, 9, 0]

my_list = my_list + [343, 564]

print(my_list)

#OUTPUT
[2, 3, 4, 5, 5, 7, 8, 1, 5, 6, 2, 9, 0, 343, 564]
```

{% endtab %}
{% endtabs %}

The `+=` augmented assignment operator works only when we append elements to a list&#x20;

{% tabs %}
{% tab title="Prepend" %}

```python
# Elements addition
my_list = [2, 3, 4, 5, 5, 7, 8, 1,5, 6, 2, 9, 0]

[343, 564] += my_list

#OUTPUT
  File "<ipython-input-9-3ec7d1771475>", line 3
    [343, 564] += my_list
                         ^
SyntaxError: can't assign to literal
```

{% endtab %}

{% tab title="Append" %}

```python
# Elements addition
my_list = [2, 3, 4, 5, 5, 7, 8, 1,5, 6, 2, 9, 0]

my_list += [343, 564]

print(my_list)

#OUTPUT
[2, 3, 4, 5, 5, 7, 8, 1, 5, 6, 2, 9, 0, 343, 564]
```

{% endtab %}
{% endtabs %}

The `*` operator repeats a list for a given number of times.

{% tabs %}
{% tab title="Code" %}

```python
my_cities = ['Krakow', 'Warsaw', 'Lodz', 'Kielce']

my_cities * 3
```

{% endtab %}

{% tab title="Ouput" %}

```python
['Krakow', 'Warsaw', 'Lodz', 'Kielce', 
 'Krakow', 'Warsaw', 'Lodz', 'Kielce', 
 'Krakow', 'Warsaw', 'Lodz', 'Kielce']
```

{% endtab %}
{% endtabs %}

## List methods

list methods modify the target list in place. They do not return a new list. We do not need to use assignment operators such as `=`.

### `append()`

You can use `append()` to added an element to the end of a list.&#x20;

{% tabs %}
{% tab title="First Tab" %}

```python
age = [23, 45, 89, 18, 24, 29, 36]

age.append(57)
```

{% endtab %}

{% tab title="Output" %}

```python
[23, 45, 89, 18, 24, 29, 36, 57]
```

{% endtab %}
{% endtabs %}

A list can be added to another list, but it will append the list as a sublist rather than extending the elements within the main list (it is added as a single object).

{% tabs %}
{% tab title="Code" %}

```python
age = [23, 45, 89, 18, 24, 29, 36]

age.append([57, 34, 19])
```

{% endtab %}

{% tab title="Output" %}

```python
[23, 45, 89, 18, 24, 29, 36, [57, 34, 19]]
```

{% endtab %}
{% endtabs %}

### `extend()`

Similar to `append()`, `extend()` also adds element/s to the end of a list and only modifies the original list. the argument between `()` should be an iterable, i.e., adding an element at a time.

{% tabs %}
{% tab title="Code" %}

```python
age = [23, 45, 89, 18, 24, 29, 36]

age.extend([57, 34, 19])
```

{% endtab %}

{% tab title="Output" %}

```python
[23, 45, 89, 18, 24, 29, 36, 57, 34, 19]
```

{% endtab %}
{% endtabs %}

You can see the difference between `append()` and `extend()` methods when adding a list to a list. `append()` adds as a sublist but `extend()` adds an element at a time

### `insert()`

You can insert one element at a desired location by using the method `insert()`. insert() takes two arguments:&#x20;

1. The index location to add the element and&#x20;
2. the element (string, float, integer etc).

The newly inserted element will push the elements from the index insert location to the right.

{% tabs %}
{% tab title="Code" %}

```python
['Krakow', 'Warsaw', 'Lodz', 'Kielce']
my_cities.insert(2, 'Poznan')
```

{% endtab %}

{% tab title="Output" %}

```python
['Krakow', 'Warsaw', 'Poznan', 'Lodz', 'Kielce']
```

{% endtab %}
{% endtabs %}

### `pop()`&#x20;

The `pop()` **removes** and **returns** the last element when no index is provided. You can use `pop()` with an index to remove element at the given index. `pop()` is helpful because it may insert or remove an element from only one end, as a result, lists can be implemented as stacks (last-in, first-out).

{% tabs %}
{% tab title="Code" %}

```python
my_cities = ['Krakow', 'Warsaw', 'Warsaw', 'Lodz', 'Kielce']

# pop() returns last element
my_cities.pop()

# Above list misses last element
print(my_cities)
```

{% endtab %}

{% tab title="Output" %}

```python
# Output for pop()
'Kielce'

# Our list after applying pop()
['Krakow', 'Warsaw', 'Warsaw', 'Lodz']
```

{% endtab %}
{% endtabs %}

### `remove()`

You can use `remove()` method to remove a given element. You have to provide the element (not its index).

{% tabs %}
{% tab title="Code" %}

```python
my_cities = ['Krakow', 'Warsaw', 'Lodz', 'Kielce']

my_cities.remove('Krakow')
```

{% endtab %}

{% tab title="Output" %}

```python
['Warsaw', 'Lodz', 'Kielce']
```

{% endtab %}
{% endtabs %}

`remove()` removes only the **FIRST** occurrence of the element.

{% tabs %}
{% tab title="Code" %}

```python
my_cities = ['Krakow', 'Warsaw', 'Warsaw', 'Lodz', 'Kielce']

my_cities.remove('Warsaw')
```

{% endtab %}

{% tab title="Output" %}

```python
['Krakow', 'Warsaw', 'Lodz', 'Kielce']
```

{% endtab %}
{% endtabs %}

You can check the Jupyter Notebook in GitHub or Colab.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://zmnako.gitbook.io/datascience/lists.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
