2

This is code in IDLE2 in python, and error.

I need to include each "data" element as key and value "otro", in an orderly manner. Well "data" and "otro" it's list with 38 string's, as for "dik" it's an dictionary.

>>> for i in range(len(otro)+1):
    dik[dato[i]] = otro[i]  

Traceback (most recent call last):
  File "<pyshell#206>", line 2, in <module>
    dik[dato[i]] = otro[i]
IndexError: list index out of range
>>> 

this problem is range(0, 38) output -> (0, 1,2,3 ... 37) and it is all messy

mgilson
  • 300,191
  • 65
  • 633
  • 696
opmeitle
  • 195
  • 6
  • 19

2 Answers2

13

I think something like:

dik = dict(zip(dato,otro))

is a little cleaner...


If dik already exists and you're just updating it:

dik.update(zip(dato,otro))

If you don't know about zip, you should invest a little time learning it. It's super useful.

a = [ 1 , 2 , 3 , 4 ]
b = ['a','b','c','d']
zip(a,b)   #=>   [(1,'a'),(2,'b'),(3,'c'),(4,'d')] #(This is actually a zip-object on python 3.x)

zip can also take more arguments (zip(a,b,c)) for example will give you a list of 3-tuples, but that's not terribly important for the discussion here.

This happens to be exactly one of the things that the dict "constructor" (type) likes to initialize a set of key-value pairs. The first element in each tuple is the key and the second element is the value.

mgilson
  • 300,191
  • 65
  • 633
  • 696
10

The error comes from this: range(len(otro)+1). When you use range, the upper value isn't actually iterated, so when you say range(5) for instance, your iteration goes 0, 1, 2, 3, 4, where position 5 is the element 4. If we then took that list elements and said for i in range(len(nums)+1): print nums[i], the final i would be len(nums) + 1 = 6, which as you can see would cause an error.

The more 'Pythonic' way to iterate over something is to not use the len of the list - you iterate over the list itself, pulling out the index if necessary by using enumerate:

In [1]: my_list = ['one', 'two', 'three']

In [2]: for index, item in enumerate(my_list):
   ...:     print index, item
   ...:
   ...:
0 one
1 two
2 three

Applying this to your case, you can then say:

>>> for index, item in enumerate(otro):
...    dik[dato[index]] = item 

However keeping with the Pythonicity theme, @mgilson's zip is the better version of this construct.

mgilson
  • 300,191
  • 65
  • 633
  • 696
RocketDonkey
  • 36,383
  • 7
  • 80
  • 84