Sharl
Sharl

Reputation: 185

TypeError: argument of type 'Item' is not iterable

So I've created an object 'Item' which contains a list within a list

        for item in stock_list:
            item_list = item.split(",")
            self.__items += [Item(item_list[0], item_list[1], float(item_list[2]), int(item_list[3]))]

When trying to find the item which matches the code (index 0) I am trying to create a new function to return this item

def find_item(self, code):
    for item in self.__items:
        if code in item:
            print(item)

When I run this it gives me the TypeError: argument of type 'Item' is not iterable error and I can't figure out why? Should I create a getCode() function which returns the private self.__code? Or would that not make a difference?

Upvotes: 2

Views: 3019

Answers (1)

Anand S Kumar
Anand S Kumar

Reputation: 90999

I guess the issue occurs in line -

if code in item:

For custom classes, you cannot do - x in C - where C is an object (instance) of a custom class, unless the custom class has a __contains__() method . Example -

>>> class CC:
...     pass
...
>>> class CB:
...     def __contains__(self, item):
...             if item == 1:
...                     return True
...             else:
...                     return False
...
>>> cco = CC()
>>> cbo = CB()
>>> 1 in cco
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: argument of type 'CC' is not iterable
>>> 1 in cbo
True
>>> 2 in cbo
False

But given this, __contains__() is basically used for membership test where an object can contain multiple elements (take list/dict as examples),

If you are trying to compare code is equal to some other variable like self.__code . Then you would either need to provide some kind of method (or property) that returns __code , if __code is again some kind of list or such, and you are trying to check if item is in self.__code , you can override the __contains__() as shown above.

Upvotes: 1

Related Questions