Question

I'm trying to run a for loop. Here's the section of my code I'm having trouble with:

aldurstengd_ororka = {(18, 19, 20, 21, 22, 23, 24):1, (25):0.95, (26):0.90,
    (27):0.85, (28, 29):0.75, (30, 31):0.65, (32, 33):0.55, (34, 35):0.45,
    (36, 37):0.35, (40, 41, 42, 43, 44, 45):0.15, (46, 47, 48, 49, 50):0.10,
    (51, 52, 53, 54, 55):0.075, (56, 57, 58, 59, 60):0.05, (61, 62, 63, 64,
    65, 66):0.025}

for age in aldurstengd_ororka.keys():
    for item in age:
       if ororkualdur == item:
           baetur = baetur + ororkulifeyrir * aldurstengd_ororka([age])

So my intention is to run through aldurstengd_ororka, and for each "age" tuple in the dictionary, I run another for loop for each "item" inside the tuple. The error I get is

TypeError: 'int' object is not iterable

Was it helpful?

Solution

If aldurstengd_ororka is a dictionary, then this expression:

aldurstengd_ororka([age])

is an error. Perhaps you meant something like:

aldurstengd_ororka[(age)]

EDIT: The error you were seeing is quite interesting, I did reproduce it with this snippet:

for age in aldurstengd_ororka.keys():
    print 'age:', age 
    for item in age:
        print item

The output of the code is:

age: (32, 33)
32
33
age: (36, 37)
36
37
age: (51, 52, 53, 54, 55)
51
52
53
54
55
age: (61, 62, 63, 64, 65, 66)
61
62
63
64
65
66
age: (30, 31)
30
31
age: 25
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)

/home/ma/mak/Documents/t.py in <module>()
      3 for age in aldurstengd_ororka.keys():
      4     print 'age:', age
----> 5     for item in age:
      6         print item
      7 

TypeError: 'int' object is not iterable

So, what happens is Python 'unpacks' a tuple of 1 element when assigning it to the age variable. So age instead of (25), as you would expect, is just 25... It's a bit strange. A workaround would be to do something like:

for age in aldurstengd_ororka.keys():
    # if not tuple, make it a tuple:
    if not type(age) == type( (0,1) ): age = (age,)
    print 'age:', age 
    for item in age:
        print item

OTHER TIPS

Your tuple keys that just have a single int in them are being parsed as an int instead of a tuple. So when you try to for item in age - you're trying to iterate through a non-iterable. Use lists [4] or use a comma (4,), and it'll do the trick:

aldurstengd_ororka = {(18, 19, 20, 21, 22, 23, 24):1, (25):0.95, (26):0.90,
    (27):0.85, (28, 29):0.75, (30, 31):0.65, (32, 33):0.55, (34, 35):0.45,
    (36, 37):0.35, (40, 41, 42, 43, 44, 45):0.15, (46, 47, 48, 49, 50):0.10,
    (51, 52, 53, 54, 55):0.075, (56, 57, 58, 59, 60):0.05, (61, 62, 63, 64,
    65, 66):0.025}

for age in aldurstengd_ororka.keys():
    if isinstance(age, [tuple, list]):
       for item in age:
           if ororkualdur == item:
               baetur = baetur + ororkulifeyrir * aldurstengd_ororka[age]
    else:
        baetur = baetur + ororkulifeyrir * aldurstengd_ororka[age]

I hate to say this, but both sihrc and piokuc are wrong.

You have a dictionary of the format:

d = { (1,2,3) : "a",
      (4) : "b"
    }

The first key (1,2,3) is a tuple with 3 integers in it. The second key (4) is just an integer with the value 4, not a tuple. The defining characteristic of a tuple is the comma separating the values, not the braces, thus a = 1,2,3 creates a tuple, and assigns it to a.

The main purpose of braces around tuples is to make the code look cleaner and to simplify some of the edge cases, such as single item tuples.

To convert the 4 into a single item tuple, you need to do something slightly odd, add a trailing comma after the value, thus (4,).

If you do this to all the single item keys in your dictionary, you should find that it work OK.

The dictionary keys are sometimes tuples and sometimes integers. As @Simon Callan mentioned you can add commas to the numbers to make all keys iterable.

If you do not wish to edit your dictionary, use a tool from the more_itertools library that always returns an iterable.

Reduced Example:

import more_itertools as mit

d = {
    (18, 19, 20, 21, 22, 23, 24): 1, 
    (25): 0.95, 
    (26): 0.90,
    (27): 0.85, 
    (28, 29): 0.75,
}

for age in d:
    for item in mit.always_iterable(age):
        # Add logic here
        pass

# No TypeError

See the docs for details.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top