# Lists and Tuples
Elixir has two collection types: (Linked) Lists and Tuples.
## Lists
A `List` is defined with square brackets and can contain elements of different data types:
```elixir
details = ["Peter", 32, 190.47, true, :active]
```
Lists are not stored contiguously in memory because they are implemented as [linked lists](https://en.wikipedia.org/wiki/Linked_list). Each element is stored in memory with its value and a pointer to the next element. This structure makes traversing, updating, deleting, and appending values slow, but prepending new values fast. For more information, see the [Big-O Time Complexities](09-misc/big-o.livemd) section.
You can access elements in various ways:
```elixir
details = ["Peter", 32, 190.47, true, :active]
# Get the 2nd element, because lists are 0-based.
Enum.at(details, 1) # => 32
# Get the last element with a negative index
Enum.at(details, -1) # => :active
# Or use the `List` helper functions
List.first(details) # => "Peter"
List.last(details) # => :active
# Update an element at a specific index
List.replace_at(details, 1, 30)
# => ["Peter", 30, 190.47, true, :active]
# Prepend a value to the list
[:adult | details]
# => [:adult, "Peter", 32, 190.47, true, :active]
# Concatenate two lists
details ++ [nil, 123]
# => ["Peter", 32, 190.47, true, :active, nil, 123]
# Delete the first occurrence of an element
List.delete(details, 32)
# => ["Peter", 190.47, true, :active]
# Delete an element at a specific index
List.delete_at(details, -1)
# => ["Peter", 32, 190.47, true]
```
## Tuples
A `Tuple` is stored contiguously in memory. That makes accessing an element by its index or getting the tuple size a fast operation.
```elixir
hobbies = {"Sport", "Coffee", "Writing"}
# Get the first element
elem(hobbies, 0) # => "Sport"
# Update an element
put_elem(hobbies, 2, "Reading")
# => {"Sport", "Coffee", "Reading"}
# Append an element
Tuple.append(hobbies, "Coding")
# => {"Sport", "Coffee", "Writing", "Coding"}
# Delete an element at a specific index
Tuple.delete_at(hobbies, 1)
# => {"Sport", "Writing"}
# Get the Tuple size
tuple_size(hobbies) # => 3
```
If you look closely at the output above, you'll see that although we update and append elements to our tuple, the original `hobbies` variable is not modified. In Elixir, variables are immutable and every function call => a copy of the input variable instead of a modified version of the original variable.