# Dictionary

Dictionaries and lists share the following characteristics:

* Both are mutable.
* Both are dynamic. They can grow and shrink as needed.
* Both can be nested. A list can contain another list. A dictionary can contain another dictionary. A dictionary can also contain a list, and vice versa.

Dictionaries differ from lists primarily in how elements are accessed:

* List elements are accessed by their position in the list, via indexing.
* Dictionary elements are accessed via keys.

### What is dictionary in Python?

Python dictionary is an unordered collection of elements. While other compound data types have only value as an element, a dictionary has a **key:value** pair.

Dictionaries are optimised to retrieve values when the key is known.

### Defining a Dictionary <a href="#defining-a-dictionary" id="defining-a-dictionary"></a>

Dictionaries are Python’s implementation of a data structure that is more generally known as an associative array. A dictionary consists of a collection of key-value pairs. Each key-value pair maps the key to its associated value.

You can define a dictionary by enclosing a comma-separated list of key-value pairs in curly braces (`{}`). A colon (`:`) separates each key from its associated value:

```python
dict = {
    <key>: <value>,
    <key>: <value>,
      .
      .
      .
    <key>: <value>
}
```

The following defines a dictionary that maps a location to the name of its corresponding Major League Baseball team:

```python
mlb_team = {
     'Colorado' : 'Rockies',
     'Boston'   : 'Red Sox',
     'Minnesota': 'Twins',
     'Milwaukee': 'Brewers',
     'Seattle'  : 'Mariners'
     }
```

You can also construct a dictionary with the built-in `dict()` function. The argument to `dict()` should be a sequence of key-value pairs. A list of tuples works well for this:

```python
d = dict([
    (<key>, <value>),
    (<key>, <value),
      .
      .
      .
    (<key>, <value>)
])
```

```python
mlb_team = dict([
     ('Colorado', 'Rockies'),
     ('Boston', 'Red Sox'),
     ('Minnesota', 'Twins'),
     ('Milwaukee', 'Brewers'),
     ('Seattle', 'Mariners')
     ])
```

If the key values are simple strings, they can be specified as keyword arguments. So here is yet another way to define `mlb_team`:

```python
mlb_team = dict(
     Colorado='Rockies',
     Boston='Red Sox',
     Minnesota='Twins',
     Milwaukee='Brewers',
     Seattle='Mariners'
     )
```

Once you’ve defined a dictionary, you can display its contents, the same as you can do for a list. All three of the definitions shown above appear as follows when displayed:

```python
print(type(mlb_team))
# output
<class 'dict'>

print(mlb_team)

# output
{'Colorado': 'Rockies', 'Boston': 'Red Sox', 'Minnesota': 'Twins',
'Milwaukee': 'Brewers', 'Seattle': 'Mariners'}
```

Indexing do not work on dictionaries

```python
print(mlb_team[1])

KeyError                                  Traceback (most recent call last)
<ipython-input-28-6ab878e87e84> in <module>()
----> 1 print(mlb_team[0])

KeyError: 0
```

### How to access elements from a dictionary?

While indexing is used with other container types to access values, dictionary uses keys. Key can be used either inside square brackets or with the `get()` method.

The difference while using `get()` is that it returns `None` instead of `KeyError`, if the key is not found.

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

```python
my_dict = {'name':'John Legend', 'age': 79}

# method 1
print(my_dict['name'])

# method 2
print(my_dict.get('age'))
```

{% endtab %}

{% tab title="Output" %}

```python
# method 1 output
John Legend

# method 2 output
79
```

{% endtab %}
{% endtabs %}

### How to change or add elements in a dictionary?

Dictionary are mutable. We can add new elements or change the value of existing elements using assignment operator.

If the key is already present, value gets updated, else a new key: value pair is added to the dictionary.

#### Update a value

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

```python
my_dict = {'name':'John', 'age': 72}

# update a value
my_dict['age'] = 27

print(my_dict)
```

{% endtab %}

{% tab title="Output" %}

```python
{'name': 'John', 'age': 27}
```

{% endtab %}
{% endtabs %}

#### Add an element (key and value pair)

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

```python
my_dict = {'name':'John', 'age': 72}

# add element
my_dict['address'] = 'Krakow'  

print(my_dict)
```

{% endtab %}

{% tab title="Output" %}

```python
{'name': 'John', 'age': 72, 'address': 'Krakow'}
```

{% endtab %}
{% endtabs %}

#### Delete elements

We can remove a particular element in a dictionary by using the method `pop()`. This method removes an element with the provided key and returns the value.

The method, `popitem()` can be used to remove and return an arbitrary or last element (key, value) from the dictionary. All the elements can be removed at once using the `clear()` method.

We can also use the `del` keyword to remove individual elements or the entire dictionary itself.

**`pop()`**

`pop()` method expects a location of the key and value pair. Index in dictionary starts from **ONE**.

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

```python
# create a dictionary
tens = {1:10, 2:20, 3:30, 4:40, 5:50}  

# remove a particular element
print(tens.pop(2))

# The remaining dictionary pairs
print(tens)
```

{% endtab %}

{% tab title="Output" %}

```python
# print(tens.pop(2))
20

# print(tens)
{1: 10, 3: 30, 4: 40, 5: 50}
```

{% endtab %}
{% endtabs %}

**`popitem()`**

`popitem()` remove the last key and value pair from the dictionary.

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

```python
# create a dictionary
tens = {1:10, 2:20, 3:30, 4:40, 5:50}

# remove a particular element
print(tens.popitem())

# The remaining dictionary pairs
print(tens)
```

{% endtab %}

{% tab title="Output" %}

```python
# print(tens.popitem())
(5, 50)

# print(tens)
{1: 10, 2: 20, 3: 30, 4: 40}
```

{% endtab %}
{% endtabs %}

**`del`**

You can use `del` method to delete a key and value pair based on the index location, remember index starts from **ONE** in the dictionaries. You can use `del` to delete the whole dictionary as well.

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

```python
# create a dictionary
tens = {1:10, 2:20, 3:30, 4:40, 5:50}

# delete a particular element
del tens[2]  

print(tens)
```

{% endtab %}

{% tab title="Output" %}

```python
# print(tens)
{1: 10, 3: 30, 4: 40, 5: 50}
```

{% endtab %}
{% endtabs %}

**`clear()`**

`clear()` method can be use to delete all key and pair values in the dictionary, it returns an empty dictionary.

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

```python
# create a dictionary
tens = {1:10, 2:20, 3:30, 4:40, 5:50}

# remove all elements
tens.clear()

print(tens)
```

{% endtab %}

{% tab title="Output" %}

```python
# print(tens)
{}
```

{% endtab %}
{% endtabs %}

### Python Dictionary Methods

Methods that are available with dictionary are tabulated below. Some of them have already been used in the above examples.

| Method               | Description                                                                                                                              |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| clear()              | Remove all elements form the dictionary.                                                                                                 |
| copy()               | Return a shallow copy of the dictionary.                                                                                                 |
| fromkeys(seq\[, v])  | Return a new dictionary with keys from seq and value equal to v (defaults to `None`).                                                    |
| get(key\[,d])        | Return the value of key. If key doesnot exit, return d (defaults to `None`).                                                             |
| items()              | Return a new view of the dictionary's elements (key, value).                                                                             |
| keys()               | Return a new view of the dictionary's keys.                                                                                              |
| pop(key\[,d])        | Remove the element with key and return its value or d if key is not found. If d is not provided and key is not found, raises `KeyError`. |
| popitem()            | Remove and return a random element (key, value). Raises `KeyError` if the dictionary is empty.                                           |
| setdefault(key\[,d]) | If key is in the dictionary, return its value. If not, insert key with a value of d and return d (defaults to `None`).                   |
| update(\[other])     | Update the dictionary with the key/value pairs from other, overwriting existing keys.                                                    |
| values()             | Return a new view of the dictionary's values                                                                                             |

### Python Dictionary Comprehension

Dictionary comprehension is an elegant and concise way to create new dictionary from an iterable in Python.

Dictionary comprehension consists of an expression pair (key: value) followed by `for` statement inside `curly brackets {}`.

Here is an example to make a dictionary with each item being a pair of a number and its square.

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

```python
tens = {x: x*10 for x in range(1, 6)}

print(tens)
```

{% endtab %}

{% tab title="Output" %}

```python
{1: 10, 2: 20, 3: 30, 4: 40, 5: 50}
```

{% endtab %}
{% endtabs %}

A dictionary comprehension can optionally contain more **for** or **if statements**.

An optional `if` statement can filter out items to form the new dictionary.

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

```python
tens = {x: x*10 for x in range(1, 20) if x%3==1}

print(tens)
```

{% endtab %}

{% tab title="Output" %}

```python
# print(tens)
{1: 10, 4: 40, 7: 70, 10: 100, 13: 130, 16: 160, 19: 190}
```

{% endtab %}
{% endtabs %}
