Skip to content Skip to sidebar Skip to footer

Why Is 'int" Not Iterable In Python, But 'str' Are?

I'm getting some practice with list comprehensions and I ran into the following error: Find all of the numbers from 1-1000 that have a 3 in them result = [i for i in range(1, 1001)

Solution 1:

Because it’s not clear what iterating over an int would do. You seem to expect that it iterates over the decimal digits (?) but I for example find that unreasonable: I’d find it much more natural to iterate over its bits (i.e. its binary digits). Inside memory, ints are represented as binary numbers, not decimal numbers, so I could argue that mine is the more natural expectation.

But since there’s no obviously right answer, Python’s designers decided not to make int iterable at all.

By contrast, for strings there’s an immediately intuitive “right” answer (although the devil is in the details): we iterate over its characters. Unfortunately that actually opens a can of worms since whole books have been written about the definition of “character”, and in practice something subtly different happens (if you’re curious, start reading The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)). But the answer “we iterate over characters” is close enough.


Solution 2:

From a conceptual perspective, the answer by @KonradRudolph is the right one.

But from a technical perspective, what makes an object able to be iterated over? This property is called being iterable. And in Python, an object is iterable as long as it implements the magic method __iter__. Magic methods are special methods Python looks for in a class if it wants to use certain built-in behavior. Like iterating over an object, or adding two objects with +.

And so, we could easily implement our own number class that is iterable:

class IterableInt:
    def __init__(self, i):
        self.i = i
    
    def __iter__(self):
        return map(int, str(self.i))

Here I chose iterable to mean what you expected, i.e. iterating over the decimal digits. Iterating over the binary digits instead would only mean changing one line.

Note that this is not really a number (yet), you cannot add or multiply it. For that one would probably want to inherit from int, but that complicates things a bit more and is left as an exercise.

In any case, now we have an iterable integer:

n = IterableInt(123)
print(3 in n)
# True
print(list(n))
# [1, 2, 3]

If you need to find out if an object is iterable, there are two ways. One is called "Look before you leap" (LBYL), you can test for the existence of the __iter__ method or use the typing module:

hasattr(n, "__iter__")
# True
hasattr(123, "__iter__")
# False

from typing import Iterable
isinstance(n, Iterable)
# True
isinstance(123, Iterable)
# False

And the other is "it’s easier to ask for forgiveness than permission" (EAFP), where you just assume the object is iterable and deal with it if it is not:

try:
    3 in 123
except TypeError:
    print("too bad, should have used IterableInt")

Solution 3:

Because a string is an array of characters. An int is not a sequence of anything (it can be represented as a sequence of digits, but that is not what it is).


Solution 4:

if you want to check the int, you have to match with every digit in the int by every tenth place.

from math import floor

def check_if_number_exists(number, digit_to_find):
    # check if the number is positive
    if number < 0:
        Number = -number
    else:
        Number = number
    while(Number != 0):
        # run loop for extracting each digit
        Digit = Number % 10 # gives the last number
        Number = floor(Number / 10) # removing the last digit
        if Digit == digit_to_find:
            print("the number contains " + str(digit_to_find) + ' in ' + str(number))
            break


check_if_number_exists(45638, 3)

you check any number you want with above code.

you cannot do the same way you did for str because int is different from string. A small example

s + e + v + e + n = seven (string is array which comprise of letters)
43567 = 40000 + 3000 + 500 + 60 + 7 (not 4+3+5+6+7)

hope you understand, why iteration dont work on int


Post a Comment for "Why Is 'int" Not Iterable In Python, But 'str' Are?"