-1

Let's say I generate a list of strings:

def printList(list)
    for i in list:
        print(i)

string = 'hello,world,!'
strings = string.split(',')
printList(strings)

This works fine. However, if the string is only one element long, or I want to call printList with a type that is not iterable, then this falls apart. Consider the following (more relevant) example:

my_list=[]
def add_items_filtered(items)
    for item in items:
        if item > 5: #arbitrary filter
            my_list.append(item)

add_items_filtered([4,5,6,7]) #this works fine
add_items_filtered(6) #this fails

The issue here is that the item I sent is not "iterable". I can work around this with:

if not isinstance(items, list):
    items=[items]

But this seems like a hack. Is the only real way to do this by forcing the caller of this function to send me in a list? It seems counterintuitive to be roadblocked by such a simple issue.

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
Brydon Gibson
  • 1,179
  • 3
  • 11
  • 22
  • well what is the expected return value of the function if you give it something thats not a list. like `add_items_filtered(some_non_iterable)` what would you expect the function to return in such a situation? – Chris Doyle Jan 10 '22 at 21:03
  • 4
    No, this is not a hack. In fact, this is how the type system works in most of the programming languages. – Ervin Szilagyi Jan 10 '22 at 21:05
  • 2
    What are you actually trying to accomplish? Like, in what context would you use the function? This seems like an [XY problem](https://meta.stackexchange.com/q/66377/343832) because it doesn't really make sense for a function that works on a vector (list) to accept a scalar (int). Maybe you want to use [`*args`](https://docs.python.org/3/tutorial/controlflow.html#arbitrary-argument-lists) instead? – wjandrea Jan 10 '22 at 21:07
  • try-except is also another solution. – S.B Jan 10 '22 at 21:09
  • The intent of this function is to add whatever is passed in into a list (after applying a filter). I would like the caller to be able to dump in a list of objects to add, instead of having to itself loop and sequentially call the add function – Brydon Gibson Jan 11 '22 at 12:54

1 Answers1

3

If you want a workaround, use

def add_items_filtered(*items):

Then you can pass arguments like

add_items_filtered(4,5,6,7)
add_items_filtered(6)

Otherwise, you'll have to check types, and there is nothing wrong with looping over a list of one element.

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • "There is nothing wrong with looping over a list of one elemet". Python throws type errors because the element that was passed in is not iterable. It's trying to iterate the item instead of the implicit list - which requires the type check – Brydon Gibson Jan 11 '22 at 14:54
  • @BrydonGibson That's not what I was referring to. As the error says, you don't have a list. I was only referring to the fact that you could have `for x in range(1)` – OneCricketeer Jan 11 '22 at 15:27
  • Understood - that makes sense, as someone who stays at the lower levels, it's hard to tell what python will implicitly do for you, and what it won't – Brydon Gibson Jan 11 '22 at 16:09