Dict comprehension with zip inside

Dear friends,

it is very hard for me to understand iterators. Can you please help?

I am trying to solve “say” exercise.
Suppose I have this simple code lines:

num_list = [999, 999, 999, 999]
order = ["", "thousand", "million", "billion"]
result_dict = {n: o for n, o in zip(num_list, order) if n > 0}

print(result_dict)

The result is:
{999: ‘billion’}

I can’t understand why result_dict only gets the last k and v from zip iterator. I expected result_dict would include all k and v from zip iterator.

Can you please help me on this?

Thanks,

Rod.

1 Like

It doesn’t; it gets all of them. However, num_list contains only 999s. As a result, the dict receives the same key four times. The first time an entry (999: "") is added, but the next three times the value is overwritten. The last value to be written is "billion", hence your result.

Try num_list [0, 1, 2, 3] for contrast.

1 Like

As @MatthijsBlom has indirectly pointed out, keys in dictionaries have to be unique. With the way your comprehension is written, you have the key portion mapped to num_list items and the values mapped to order items. Since you number list had identical values, they are all getting written as the same key. Flipping keys & values in the comprehension will get you a different result:

num_list = [999, 999, 999, 999]
order = ["", "thousand", "million", "billion"]
result_dict = {word: number for number, word in 
zip(num_list, order) if number > 0}

print(result_dict)
>>>  {'': 999, 'thousand': 999, 'million': 999, 'billion': 999}

Conversely, you can flip the order in the zip():


num_list = [999, 999, 999, 999]
order = ["", "thousand", "million", "billion"]
result_dict = {word: number for word, number in 
zip(order, num_list) if number > 0}

print(result_dict)
>>>> {'': 999, 'thousand': 999, 'million': 999, 'billion': 999}

Thank you! Now I understand! :wink:

I will try to do that.

Thank you so much,

Rod.