1

Its a bit strange to know that i keep getting a KeyError exception only in one scenario. I tried zip on two string sequences and that object was then used inside the dict function. But when i try to index this sequence out i keep getting KeyError.

>>> rawdata = "acbd"
>>> l1 = "abcd"
>>> l2 = "cdef"
>>> zp1 = zip(l1, l2)
>>> type(zp1)
<class 'zip'>
>>> # zp1 is basically used for mapping. So every character in l1 is mapped to l2. So this would be
... # used to alter the rawdata object. Meaning every char in raw data would basically act as a key
... # to the below dictionary object and return a value which is then used in the join function.
...
>>> newstring = ''
>>> newstring = ''.join([dict(zp1)[x] for x in rawdata])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <listcomp>
KeyError: 'c'

The funny this is the same code works properly if i dont use the zp1 object rather i use zip(l1, l2) inside dict directly. Why does this happen? Any clues? Below is the code that works well.

>>> rawdata = "acbd"
>>> l1 = "abcd"
>>> l2 = "cdef"
>>> newstring = ''.join([dict(zip(l1, l2))[x] for x in rawdata])
>>> print(newstring) # Working as expected, without any exception
cedf
Abhishek
  • 155
  • 3
  • 14
  • `dict(zp1)[x]` is creating a new dictionary for every `x in rawdata`. This is both: 1. obviously inefficient; and 2. causing your specific problem, because the `zip` object gets consumed the first time you turn it into a dictionary. Therefore for every `x in rawdata[1:]`, `dict(zp1) == {}`. Move the dictionary definition **outside the comprehension**, your alternative solution of repeating the whole `zip` and `dict` process for every character in `rawdata` is even less efficient. – jonrsharpe Mar 10 '18 at 12:01
  • @jonrsharpe : why does this work then '[dict(zip(l1, l2))[x] for x in rawdata]' ?? Sorry i dint actually get what you are tying to say. :( – Abhishek Mar 10 '18 at 12:06
  • Because that's also creating a new `zip` object for every `x in rawdata`. But given that `dict(zip(l1, l2))` is always the same, even if you weren't having this issue that should not be done inside a loop. – jonrsharpe Mar 10 '18 at 12:06
  • okay so in 'dict(zp1)[x] for x in rawdata' would the the dictionary get created first? Then if has been created cant we use x in rawdata to get the items from the dictionary. I mean how can it be empty.. {} I went through the iterators and came to know how the zip objects gets exhausted after an iteration. But that doesn't explain how we cant use the dictionary that is created in the first instance.. sorry to keep bothering, i know it duplicate. But this query hasn't been answered before. Please advice. – Abhishek Mar 10 '18 at 12:24

0 Answers0