---
jupytext:
  formats: content_md///md:myst,content///ipynb
  text_representation:
    extension: .md
    format_name: myst
    format_version: 0.13
    jupytext_version: 1.16.4
kernelspec:
  display_name: Python 3 (ipykernel)
  language: python
  name: python3
---

(python:lists-friends:tuples)=
# Tuples

Tuples are *immutable* objects which hold a *fixed-size* list of other objects. Imagine tuples as a list of pointers to objects, where the number of pointers and the pointers themselve cannot be changed. But note, that the objects the tuple entries point to can change if they are mutable. Object type for tuples is `tuple`.

## Syntax

Tuples are defined as a comma separated list. Often the list is surrounded by parentheses:

```{code-cell} ipython3
a = (1, 5, 9)                            # a tuple of integers
b = 2, 3, 4                              # works also without parentheses
c = ('some string', 'another_string')    # tuple of strings
d = (42, 'some string', 1.23)            # tuple with mixed types
```

Tuples with only one item are allowed, too. To distinguish them from single objects, a trailing comma is required.

```{code-cell} ipython3
a = 1       # integer     
b = (1)     # integer
c = 1,      # tuple containing one integer
d = (1,)    # tuple containing one integer
```

## Indexing

Tuple items can be accessed by index. The first item has index 0, the second index 1, and so on. The length of a tuple is returned by the built-in function `len`. Indexing with negative numbers gives the items in reverse order.

```{code-cell} ipython3
colors = ('red', 'green', 'blue', 'yellow')

print(colors[2])
print(colors[-1])
print(len(colors))
print(colors)
```

Subtuples can be extracted by so called *slicing*. Simply provide a range of indices: `[2:5]` gives a new tuple consisting of the items 2, 3, 4. The new tuple is a new object and remains available even if the original tuple vanishes (cf. [](python:variables:efficiency:garbage-collection)).

```{code-cell} ipython3
some_colors = colors[1:3]
print(some_colors[0])
print(some_colors)
```

Extracting every second item can be done by `[3:10:2]`, which gives items with indices 3, 5, 7, 9. The general syntax is `[first_index:last_index_plus_one:step]`. Here are some more indexing examples:

```{code-cell} ipython3
print(colors[2:])               # from 2 to end
print(colors[2:len(colors)])    # from 2 to end
print(colors[2:-1])             # from 2 to last but one
print(colors[:3])               # from 0 to 2
print(colors[:])                # all
```

## Tuple Assignments

Tuples can be used for returning more than one value from a function. For this purpose Python provides the following code construct:

```{code-cell} ipython3
a, b, c = 23, 42, 6
print(a, b, c)
```

That is, we can assign the contents of a tuple to a tuple of names. Such constructions typically are used if a function returns several return values packed into a tuple.

```{code-cell} ipython3
def integer_division(a, b):

    c = a // b
    d = a % b

    return c, d
    
quotient, remainder = integer_division(100, 13)

print(quotient)
print(remainder)
```

## Tuples From Lists

Lists may be converted to tuples via usual type convertion:

```{code-cell} ipython3
some_list = [1, 2, 3, 4, 5]
some_tuple = tuple(some_list)
```

Note that both list and tuple point to the some items. Items aren't copied! Modifying (mutable) list items will modify tuple items, too. See [](python:lists-friends:lists:copies) for more details.
