简体   繁体   中英

Getting TypeError: argument of type 'int' is not iterable in Python

I'm trying to write a text game with what I've learned so far, but I ran into a problem.

When I input 1, it's fine, but when I input 2, it gives me the following error:

Traceback (most recent call last):
  File "ex36.py", line 39, in <module>
    start()
  File "ex36.py", line 27, in start
    if choice == 1 or "closer" in choice:
TypeError: argument of type 'int' is not iterable

I realize that the function idf(): is totally unnecessary as I can just treat the input 2 as a string without converting it into an integer. This fixes the program. However, I would like to know why this error occurs when I try to change the input into a string, and why it only works for 1 and not 2.

I'm sorry for this stupid question; I'm very new to programming and trying to teach myself python. Thanks for the support, everyone.

Update 1: I think I see the problem now, as pointed out by two answerers below. The problem happens when the program tries to check "closer", which is a string, in choice, which is an integer.

I would like the if statements to accept both integers and strings. How would I do this? Any advice to modify my program?

from sys import exit

print("""Welcome to my text game! You may input numbers (e.g. 1, 2, 3) to
navigate or type in your choice.""", "\n")

def bad_news(reason):
    print(reason)
    exit(0)

#IDs if str or int
def idf(check):
    if check.isdigit() == True:
        converted = int(check)
        return converted
    else:
        return check

def start():
    print("You're walking home down a dark road, in a dark and gloomy night.")
    print("There's someone going the same way as you.")
    print("'It's quite dark and dangerous,' you think. 'Better do something.'")
    print("Will you: 1. Follow him/her closer? or 2. Keep distance?")
    choice1 = input("> ")

    choice = idf(choice1)

    if choice == 1 or "closer" in choice:
        bad_news("""The person gets spooked and you got cops called on you.
Now you have a restraining order. Great!""")
    elif choice == 2 or "distance" in choice:
        alley()
    else:
        print("The input is invalid; please try again.")
        start()

def alley():
    print("Now in alley.")

start()

Your idf converts any digit strings into numbers and then you try to check if a string is in the integer.

Your best option is to just always return strings from idf (or remove this function altogether) and check if choice == "1"

Your main problem is this line:

if choice == 1 or "closer" in choice:

If choice is not 1 you cannot check "closer" in choice without potential errors, because choice can still be an integer (eg the number 2 ) and an integer is not iterable.

It is best to keep the program simple and also to keep the return type from the input() function, ie the string. The string method is_digit() already exists and you can also apply it directly to the return value. In my opinion, there is no need to write another function that checks this. Then the function can also return two different data types. This complicates the code unnecessarily.

The string method is_digit() already does all the magic that is essential to your problem. It allows you to check if a user has entered a number or a text. You only need to explicitly convert the potential number to an integer ( int(choice) ) if you want to save the number as an integer.

Since you have several cases that you need to handle differently, you will also need to write some if -statements. So you could simply do something like this, for example:

if not choice.isdigit():
    if "closer" in choice:
        # do something
    elif "whatever" in choice:
        # do something
elif choice == "1":
    # do something
elif choice == "2":
    # do something
...

You can save one indentation by using the logical and -operator, but this is more a matter of taste, eg:

if not choice.isdigit() and "closer" in choice:
    ...

If you just want to react to certain return values, you can even do it without the is_digit() function, at all. But you mentioned in the question that you still want to distinguish between numbers and text (at least that's how I understood it). Because then you always get a string back and this string is always iterable. The error from above would simply not occur.


Most of it you have already figured out yourself, but the answer should also have added value for other readers. Therefore I have revised the answer again and hopefully clarified the problem better.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM