> For the complete documentation index, see [llms.txt](https://zmnako.gitbook.io/datascience/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://zmnako.gitbook.io/datascience/tuples.md).

# Tuple

## What are tuples?

In Python, tuples are similar to [lists](/datascience/lists.md) except tuples are immutable. While lists are mutable and you can change/modify elements in a tuple after the tuple is created, but you cannot change the elements of a tuple once the tuple is created.&#x20;

## Tuples vs Lists

1. Elements of a **tuple** are enclosed in **parenthesis** `()` whereas the elements of **list** are enclosed in **square bracket** `[]`.
2. The elements of a **list** are **mutable** whereas the elements of a **tuple** are **immutable**.
3. It is recommended to use tuple data type when you do not modify data and use list data type when you plan to update/modify/change data in the near future.
4. Iterating over the elements of a **tuple** is faster compared to iterating over a **list**.

## When to use tuples?

It is good to use tuples when&#x20;

1. you are not changing your data over time.
2. There's a strong culture of tuples being for heterogeneous collections.
3. Iterating over the elements of a **tuple** is fast so it is recommend to be used when doing iterations of immutable data collections.
4. Python dictionary requires tuple as one of its components, a value that is of an immutable type. A tuple can be used for this purpose, whereas a list can’t be.

## How to create tuples?

You can create a tuple by placing all the elements inside parentheses `()`, separated by **commas** `,`.&#x20;

Normally, parentheses are **NOT** necessary and a tuple can be created as a comma separated elements. However, it is a **good practice** to use parentheses.

Similar to a list,  a tuple elements can contain different data types (string, integer, float, list, another tuple, etc.).

### Create tuple with `()`

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

```python
# An empty tuple
my_tuple = ()
print(my_tuple)
```

{% endtab %}

{% tab title="Output" %}

```python
# Output: 
()
```

{% endtab %}
{% endtabs %}

A tuple contain integer

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

```python
my_tuple = (1, 2, 3)
print(my_tuple) 
```

{% endtab %}

{% tab title="Output" %}

```python
# Output: 
(1, 2, 3) 
```

{% endtab %}
{% endtabs %}

A tuple with strings

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

```python
my_tuple = ('Krakow', 'Warsaw', 'Poznan', 'Wroclaw')

print(my_tuple)
```

{% endtab %}

{% tab title="Output" %}

```python
# Output
('Krakow', 'Warsaw', 'Poznan', 'Wroclaw')
```

{% endtab %}
{% endtabs %}

Tuple with mixed datatypes

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

```python
my_tuple = (3, 10, 3.14, 'Krakow', True) 

print(my_tuple)
```

{% endtab %}

{% tab title="Output" %}

```python
(3, 10, 3.14, 'Krakow', True) 
```

{% endtab %}
{% endtabs %}

Nested tuple

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

```python
my_tuple = ('Krakow', ['zone 1', 'zone 2'], 'Warsaw', (1, 2, 3, 4))

print(my_tuple)
```

{% endtab %}

{% tab title="Output" %}

```python
('Krakow', ['zone 1', 'zone 2'], 'Warsaw', (1, 2, 3, 4))
```

{% endtab %}
{% endtabs %}

### Create tuple without `()`

A tuple can also be created without using parentheses `()`. This is called **tuple packing.**

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

```python
my_city_tuple = 'Krakow', 'Warsaw', 'Poznan', 'Wroclaw'

print(my_city_tuple)
```

{% endtab %}

{% tab title="Output" %}

```python
('Krakow', 'Warsaw', 'Poznan', 'Wroclaw')
```

{% endtab %}
{% endtabs %}

### Tuple unpacking

Each element of a tuple can be access and assigned to a new variable.

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

```python
city1, city2, city3, city4 = ('Krakow', 'Warsaw', 'Poznan', 'Wroclaw')

print(city1)
print(city2)
print(city3)
print(city4)
```

{% endtab %}

{% tab title="Output" %}

```python
# Output
Krakow
Warsaw
Poznan
Wroclaw
```

{% endtab %}
{% endtabs %}

### A single element tuple

It is a bit tricky to create a single element tuple. We cannot easily wrap an element inside a parenthesis `()`. This easily worked for a single element list.

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

```python
# string
my_tuple = ('students')

print(my_tuple)
print(type(my_tuple))

# integer
my_number_tuple = (24)

print(my_number_tuple)
print(type(my_number_tuple))
```

{% endtab %}

{% tab title="Output" %}

```python
# print(my_tuple)
'students'

# print(type(my_tuple))
<class 'str'>


# print(my_number_tuple)
24

# print(type(my_number_tuple))
<class 'int'>
```

{% endtab %}
{% endtabs %}

You need to convert from simple datatype to complex datatype of tuple, you have to add comma `,` at the end.

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

```python
# string
my_tuple = ('students', )

print(my_tuple)
print(type(my_tuple))

# integer
my_number_tuple = (24, )

print(my_number_tuple)
print(type(my_number_tuple))
```

{% endtab %}

{% tab title="Output" %}

```python
# print(my_tuple)
'students'

# print(type(my_tuple))
<class 'tuple'>


# print(my_number_tuple)
24

# print(type(my_number_tuple))
<class 'tuple'>
```

{% endtab %}
{% endtabs %}

### Access Tuple Elements

Similar to [lists](/datascience/lists.md#list-elements-can-be-accessed-by-index), you can use index operator `[]` to access an element in a tuple. Index always starts from **ZERO** in Python. You can perform all the [slicing](/datascience/lists.md#slicing-to-select-filter-elements) operations exactly as lists except tuple cannot be modified (immutable)

{% tabs %}
{% tab title="indexing code" %}

```python
my_tuple = (1, 2, 3, 4, 5, 6, 7)

my_tuple[2]
```

{% endtab %}

{% tab title="indexing output" %}

```python
# Output:
3
```

{% endtab %}

{% tab title="Negative indexing code" %}

```python
my_tuple = (1, 2, 3, 4, 5, 6, 7)

my_tuple[-3]
```

{% endtab %}

{% tab title="Negative indexing output" %}

```python
# Output
4
```

{% endtab %}
{% endtabs %}

You can use slicing operations on tuples similar to [lists](/datascience/lists.md).&#x20;

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

```python
my_tuple_cities = ('Krakow', 'Warsaw', 'Kielce', 'Katowice', 'Wroclaw')

my_tuple_cities[1:-1]
```

{% endtab %}

{% tab title="Output" %}

```python
('Warsaw', 'Kielce', 'Katowice')
```

{% endtab %}
{% endtabs %}

You can also access nested list

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

```python
my_tuple_cities = ('Krakow', 'Warsaw', [1, 2, 3], (2.1, 2.2, 2.3), 'Wroclaw')

my_tuple_cities[2][2] 
```

{% endtab %}

{% tab title="Output" %}

```python
# Output
3 # index 2 of the tuple and index 2 of the list
```

{% endtab %}
{% endtabs %}

and nested tuple as well.

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

```python
my_tuple_cities = ('Krakow', 'Warsaw', [1, 2, 3], (2.1, 2.2, 2.3), 'Wroclaw')

my_tuple_cities[3][1] 
```

{% endtab %}

{% tab title="Output" %}

```python
# Output
2.2 # index 3 of the tuple and index 1 of the nested tuple
```

{% endtab %}
{% endtabs %}

You can do concatenation of two tuples with `+` operator.

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

```python
tuple_1 = (2, 4, 6)
tuple_2 = (1, 3, 5)

tuple_1 + tuple_2
```

{% endtab %}

{% tab title="Ouput" %}

```python
# Output
(2, 4, 6, 1, 3, 5)
```

{% endtab %}
{% endtabs %}

You can also multiple a tuple multiple times with `*` operator.

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

```python
animals = ('cat', 'dog')

animals * 2
```

{% endtab %}

{% tab title="Output" %}

```python
# Output
('cat', 'dog', 'cat', 'dog')
```

{% endtab %}
{% endtabs %}

You can check the Jupyter Notebook in GitHub or Colab.
