Elixir lists vs Elixir tuples
Tags: elixir, elixirlists, elixirtuples, beginners
Published: 2019-07-12 03:07:16

---
title: Elixir lists vs Elixir tuples
published: true
description: Lists and Tuples are both ubiquitous and somewhat surprising for Elixir learners. Here's a quick guide. 
tags: Elixir, Elixir Lists, Elixir Tuples, Beginner
canonical_url: https://alchemist.camp/articles/elixir-lists-vs-tuples
---
Along with [maps](https://alchemist.camp/articles/how-to-update-elixir-maps), Lists and Tuples are both ubiquitous and somewhat surprising for Elixir learners. Here's a quick guide.

### Lists are *linked lists*

Elixir lists look just like arrays from C, Java or JavaScript, but they're not. They're not laid out contiguously in memory. They're a series of nodes where each node holds a piece of data and a pointer to the next node. The final node points to nothing.

This has performance implications. In order to read the final element in a list, you must traverse every element from the head to the tail of the list! Prepending an element to the front of the list is cheap, O(1), but accessing an element at the end is O(n)

### Tuples are more like Arrays

Elixir tuples are stored contiguously in memory. Accessing any element is O(1). On the down-side, inserting or deleting an element involves copying the entire tuple, which is O(n). Remember, like everything else in the language, Tuples are immutable!

### List elements are *usually* of the same type

This is more of a convention than a rule. Since lists implement the `Enumerable` protocol and it's very common to use functions like `Enum.map`, `Enum.reduce` and `Enum.each` that pass each element into a function, life is easier if everything in the list has the same shape.

Tuples, on the other hand are very often mixed types. They're commonly returned from functions and pattern matched against and in this case the first element is usually a status. For example:

```elixir
case retrieve_stuff do
  {:ok, stuff} -> process(stuff)
  {:err, msg} -> Logger.error("Error with message: %{msg}")
end
```

### Converting lists and tuples is easy

You can convert a list to a tuple with `List.to_tuple(some_list)` and you can convert a tuple to a list with `Tuple.to_list(some_tuple)`. For example:

```elixir
my_list = [1, 2, 3]
my_tuple = {:a, :b, :c}

other_tuple = List.to_tuple(my_list)   # equals {1, 2, 3}
other_list = Tuple.to_list(my_tuple)   # equals [:a, :b, :c]
```

- - -
## Common questions

#### How do I get the nth element of a list?
Use `Enum.at/2`. For example, `Enum.at([1, 2, 3, 4], 2)` will return `3` since lists are zero-indexed.

#### How do I get the nth element of a tuple?
Use `Kernel.elem/2`. For example, `elem({:a, :b, :c}, 0)` will return `:a` since tuples are also zero-indexed.

#### How do I insert an element into a list?
Use `List.insert_at/3`. For example, `List.insert_at([:foo, :bar, :baz], 1, :yolo)` returns `[:foo, :yolo, :bar, :baz]`. 

You can delete elements in the same way with `List.delete_at/2`.

If you're prepending to the beginning of a list (which is very performant), then you can also use a cons syntax and insert an element like this:
```elixir
my_list = [1, 2, 3]
[:hello | my_list]  # returns [:hello, 1, 2, 3]
```


#### How do I insert an element into a tuple?
Use `Tuple.insert_at/3`. For example, `Tuple.insert_at({:ok, :stuff}, 1, :yolo)` returns `{:ok, :yolo, :stuff}`.

You can delete elements in the same way with `Tuple.delete_at/2`.

#### How do I get the length of a list or a tuple?
Use `Kernel.tuple_size/1` for tuples and use `Enum.count/1` for lists.

#### What's a good reference if I need to know more?
It's best to go straight to the official docs!
- [Elixir docs: Lists](https://hexdocs.pm/elixir/List.html)
- [Elixir docs: Tuples](https://hexdocs.pm/elixir/Tuple.html)

*Request a free email-based Elixir course from [Alchemist.Camp](https://alchemist967856.typeform.com/to/FA0SUF)*