# 9.4. Comprehension Dict¶

## 9.4.1. Syntax¶

Short syntax:

>>> {x:None for x in range(0,5)}
{0: None, 1: None, 2: None, 3: None, 4: None}


Long syntax:

>>> dict((x,None) for x in range(0,5))
{0: None, 1: None, 2: None, 3: None, 4: None}


## 9.4.2. Example¶

>>> {x:x for x in range(0,5)}
{0: 0, 1: 1, 2: 2, 3: 3, 4: 4}

>>> {x:None for x in range(0,5)}
{0: None, 1: None, 2: None, 3: None, 4: None}

>>> {None:x for x in range(0,5)}
{None: 4}


## 9.4.3. Dict Collision¶

Recap information about dict keys collision. Duplicating items are overridden by the latter:

>>> data = {
...     'commander': 'Mark Watney',
...     'commander': 'Melissa Lewis',
... }
>>>
>>> data
{'commander': 'Melissa Lewis'}


While generating dict with unique keys, there are no collisions:

>>> {x:None for x in range(0,5)}
{0: None, 1: None, 2: None, 3: None, 4: None}


Although when generating dict with constant key, it will be overridden by the last one:

>>> {None:x for x in range(0,5)}
{None: 4}


## 9.4.4. Modify Key/Values¶

Modify keys:

>>> {x+10:x for x in range(0,5)}
{10: 0, 11: 1, 12: 2, 13: 3, 14: 4}


Modify values:

>>> {x:x+10 for x in range(0,5)}
{0: 10, 1: 11, 2: 12, 3: 13, 4: 14}


Modify keys and values:

>>> {x+10:x+10 for x in range(0,5)}
{10: 10, 11: 11, 12: 12, 13: 13, 14: 14}


## 9.4.5. Dict Reversal¶

Swap dict keys with values.

Algorithm:

>>> DATA = {
...     'mlewis': 'Melissa Lewis',
...     'mwatney': 'Mark Watney',
...     'rmartinez': 'Rick Martinez',
... }
>>>
>>>
>>> result = {}
>>>
>>> for username, user in DATA.items():
>>>
>>> result
{'Melissa Lewis': 'mlewis',
'Mark Watney': 'mwatney',
'Rick Martinez': 'rmartinez'}


Dict comprehension:

>>> DATA = {
...     'mlewis': 'Melissa Lewis',
...     'mwatney': 'Mark Watney',
...     'rmartinez': 'Rick Martinez',
... }
>>>
>>>
>>> result = {v:k for k,v in DATA.items()}
>>>
>>> result
{'Melissa Lewis': 'mlewis',
'Mark Watney': 'mwatney',
'Rick Martinez': 'rmartinez'}


## 9.4.6. Dict Reversal Collision¶

>>> DATA = {'a': 1, 'b': 2}
>>>
>>>
>>> {v:k for k,v in DATA.items()}
{1: 'a', 2: 'b'}


Value collision while reversing dict:

>>> DATA = {'a': 1, 'b': 2, 'c': 2}
>>>
>>> {v:k for k,v in DATA.items()}
{1: 'a', 2: 'c'}


## 9.4.7. Use Case - 0x01¶

• Even or Odd

>>> result = {}
>>>
>>> for x in range(0,5):
...     is_even = (x % 2 == 0)
...     result.update({x: is_even})
>>>
>>> print(result)
{0: True, 1: False, 2: True, 3: False, 4: True}

>>> {x: (x%2==0) for x in range(0,5)}
{0: True, 1: False, 2: True, 3: False, 4: True}


## 9.4.8. Assignments¶

"""
* Assignment: Comprehension Dict Months
* Type: class assignment
* Complexity: easy
* Lines of code: 1 lines
* Time: 3 min

English:
1. Use dict comprehension and enumerate
2. Convert MONTH into dict:
a. Keys: month number
b. Values: month name
3. Run doctests - all must succeed

Polish:
1. Użyj rozwinięcia słownikowego i enumeracji
2. Przekonwertuj MONTH w słownik:
a. klucz: numer miesiąca
b. wartość: nazwa miesiąca
3. Uruchom doctesty - wszystkie muszą się powieść

Hints:
* enumerate()

Tests:
>>> import sys; sys.tracebacklimit = 0

>>> type(result)
<class 'dict'>
>>> 0 not in result
True
>>> 13 not in result
True
>>> result[1] == 'January'
True

>>> assert all(type(x) is int for x in result.keys())
>>> assert all(type(x) is str for x in result.values())

>>> result  # doctest: +NORMALIZE_WHITESPACE
{1: 'January',
2: 'February',
3: 'March',
4: 'April',
5: 'May',
6: 'June',
7: 'July',
8: 'August',
9: 'September',
10: 'October',
11: 'November',
12: 'December'}
"""

MONTHS = ['January', 'February', 'March', 'April',
'May', 'June', 'July', 'August', 'September',
'October', 'November', 'December']

# number and month name
# type: dict[str,str]
result = ...


"""
* Type: class assignment
* Complexity: easy
* Lines of code: 1 lines
* Time: 3 min

English:
1. Use dict comprehension and enumerate
2. Convert MONTH into result: dict[str,str]:
a. Keys: month number
b. Values: month name
3. Month number must be two letter string
(zero padded) - f'{number:02}'
4. Run doctests - all must succeed

Polish:
1. Użyj rozwinięcia słownikowego i enumeracji
2. Przekonwertuj MONTH w result: dict[str,str]:
a. klucz: numer miesiąca
b. wartość: nazwa miesiąca
3. Numer miesiąca ma być dwuznakowym stringiem
(wypełnij zerem) - f'{number:02}'
4. Uruchom doctesty - wszystkie muszą się powieść

Hints:
* enumerate()
* f'{number:02}'

Tests:
>>> import sys; sys.tracebacklimit = 0

>>> type(result)
<class 'dict'>
>>> '00' not in result
True
>>> '13' not in result
True
>>> result['01'] == 'January'
True

>>> assert all(type(x) is str for x in result.keys())
>>> assert all(type(x) is str for x in result.values())
>>> assert all(len(x) == 2 for x in result.keys())

>>> result  # doctest: +NORMALIZE_WHITESPACE
{'01': 'January',
'02': 'February',
'03': 'March',
'04': 'April',
'05': 'May',
'06': 'June',
'07': 'July',
'08': 'August',
'09': 'September',
'10': 'October',
'11': 'November',
'12': 'December'}
"""

MONTHS = ['January', 'February', 'March', 'April',
'May', 'June', 'July', 'August', 'September',
'October', 'November', 'December']

# With zero-padded number and month name
# type: dict[str,str]
result = ...


"""
* Assignment: Comprehension Dict Reverse
* Type: class assignment
* Complexity: easy
* Lines of code: 1 lines
* Time: 3 min

English:
1. Use dict comprehension to reverse dict:
that is: change keys for values and values for keys
2. Run doctests - all must succeed

Polish:
1. Użyj rozwinięcia słownikowego do odwócenia słownika:
to jest: zamień klucze z wartościami i wartości z kluczami
2. Uruchom doctesty - wszystkie muszą się powieść

Hints:
* dict.items()

Tests:
>>> import sys; sys.tracebacklimit = 0

>>> assert type(result) is dict
>>> assert all(type(x) is str for x in result.keys())
>>> assert all(type(x) is int for x in result.values())
>>> assert len(result.keys()) == 3

>>> assert 'virginica' in result.keys()
>>> assert 'setosa' in result.keys()
>>> assert 'versicolor' in result.keys()

>>> assert 0 in result.values()
>>> assert 1 in result.values()
>>> assert 2 in result.values()

>>> result
{'virginica': 0, 'setosa': 1, 'versicolor': 2}
"""

DATA = {
0: 'virginica',
1: 'setosa',
2: 'versicolor'}

# type: dict[str,int]
result = ...