# 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.


---

# 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/tuples.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.
