3

I have a dictionary in the following format: dict1 = {(0, 1): [10, 11], (1, 2): [0, 0]}

I want to create another dictionary that keeps the keys as they are but removes the second value and preferably this should not be a list (since it will contain only one element)

dict2 = {(0, 1): 10, (1, 2): 0} (or even {(0, 1): [10], (1, 2): [0]})

Currently I am doing it like this:

dict2 = dict1
for key, value in dict2.items():
    dict2[key] = value[0]

I feel there might be a way to do it via dictionary comprehension. Is it possible?

KPr
  • 73
  • 4

2 Answers2

4

This way looks good... but isn't

dict2 = dict1
for key, value in dict2.items():
    dict2[key] = value[0]

print(dict2) # good so far
print(dict1) # oh no!

When we say dict2 = dict1 all we're doing is pointing the variable name dic2 to the dictionary stored at dict1. Both names will point to the same place. Superficially,

dict2 = dict1.copy()
for key, value in dict2.items():
    dict2[key] = value[0]

print(dict2) # good so far
print(dict1) # okay....

Seems to work, though you will want to look up shallow vs. deep copy if you're using more complicated structure than tuples (specifically, mutable values)

In one line, this is equivalent to

dict2 = { key : val[0] for key, val in dict1.items() }

This has the added benefit of avoiding the referencing problem from your original implementation. Again, if you have mutable types (e.g., list of lists instead of tuple of integers, there is still some chance that your values are pointing to the same place, leading to unexpected behaviour)

There are some subtle differences between dictionaries in python2 and python3. The dictionary comprehension above should work for both

Community
  • 1
  • 1
en_Knight
  • 5,301
  • 2
  • 26
  • 46
  • Great explanation, very clear and enlightening. There is a typo where you say "mutubale" i think you mean mutable. Thanks a lot – KPr Nov 25 '15 at 13:14
2

using a simple dict comp:

>>> dict1 = {(0, 1): [10, 11], (1, 2): [0, 0]}
>>> dict2 = {key:dict1[key][0] for key in dict1}
>>> dict2
{(0, 1): 10, (1, 2): 0}

you could also have it in one value lists:

>>> dict2 = {key:dict1[key][0:1] for key in dict1}
>>> dict2
{(0, 1): [10], (1, 2): [0]}

not that I used slicing so that they are copies of the values/lists, not the actual lists

R Nar
  • 5,465
  • 1
  • 16
  • 32