iterating over a variable which could be None, a single object,or a list

A

adam carr

I call a function get_items() which returns a list of items.
However, in some cases, it returns just one item.
It returns the item as an object though, not as a list containing one object.
In other cases it simply returns None.

What is the cleanest way to iterate over the return value of this function?
Or would it be better to fix the get_items() function itself to always
return lists no matter what?

Thanks,
 
S

Stefan Behnel

adam said:
I call a function get_items() which returns a list of items.
However, in some cases, it returns just one item.
It returns the item as an object though, not as a list containing one object.
In other cases it simply returns None.

What is the cleanest way to iterate over the return value of this function?
Or would it be better to fix the get_items() function itself to always
return lists no matter what?

Given the name "get_items()" in plural, I'd opt for letting it always
return a list. That also reduces the special case of returning None, where
it would now return an empty list.

Stefan
 
A

adam carr

2008/11/27 Stefan Behnel said:
Given the name "get_items()" in plural, I'd opt for letting it always
return a list. That also reduces the special case of returning None, where
it would now return an empty list.

You are of course right.

I'm still in the position of having to right code to deal with
converting None to an empty list and one object to a list with a
single entry.
Python casting doesn't work here.

Maybe it's just wishful thinking, but I would have thought there would
be a cleaner way of doing this.

Thanks,
 
A

adam carr

Denis kindly provided the following code which does this well:

def mkiter( x ):
""" list -> list, el -> [el], None -> []
usage: for x in mkiter( func returning list or
singleton ): ...
"""
return (x if hasattr( x, "__iter__" ) # list tuple ...
else [] if x is None
else [x]
)

# test --
print mkiter( 1 )
print mkiter( (2,3) )
print mkiter( None )
 
M

MRAB

adam said:
You are of course right.

I'm still in the position of having to right code to deal with
converting None to an empty list and one object to a list with a
single entry.
Python casting doesn't work here.

Maybe it's just wishful thinking, but I would have thought there would
be a cleaner way of doing this.
Do you have the source code of get_items()? That's what you should look
at and where you should fix it (unless it's just calling another
function and returning the result, etc). I wonder whether None is being
returned because it's reaching the end of the function.
 
R

Roy Smith

"adam carr said:
I call a function get_items() which returns a list of items.
However, in some cases, it returns just one item.
It returns the item as an object though, not as a list containing one object.
In other cases it simply returns None.

Almost certainly what you need to do is change the function to always
return a list. Might be a list of one object. Might be an empty list.
But always a list. Keep the interface simple and obvious and you avoid
complexities such as the one you're facing now.
 
R

r

Almost certainly what you need to do is change the function to always
return a list.  Might be a list of one object.  Might be an empty list.  
But always a list.  Keep the interface simple and obvious and you avoid
complexities such as the one you're facing now.

see this wiki for better understanding of Roy's suggestion...words to
live by my friend =D
http://en.wikipedia.org/wiki/KISS_principle
 
A

Arnaud Delobelle

adam carr said:
Denis kindly provided the following code which does this well:

def mkiter( x ):
""" list -> list, el -> [el], None -> []
usage: for x in mkiter( func returning list or
singleton ): ...
"""
return (x if hasattr( x, "__iter__" ) # list tuple ...
else [] if x is None
else [x]
)

# test --
print mkiter( 1 )
print mkiter( (2,3) )
print mkiter( None )

If you want to go this way, then why not write it simply:

def mkiter(x):
if hasattr(x, '__iter__'):
return x
return [] if x is None else [x]
 
S

Steven D'Aprano

I'm still in the position of having to right code to deal with
converting None to an empty list and one object to a list with a single
entry.
Python casting doesn't work here.

Python doesn't have type-casting. Python has type conversions:

mytype(obj)

doesn't force the type of obj to be "mytype", but constructs a new mytype
object from obj.


Maybe it's just wishful thinking, but I would have thought there would
be a cleaner way of doing this.

What's wrong with something as simple as this?

def get_items():
x = None
# lots of work here...
if isinstance(x, list): # is x list-like?
return x
else:
return [] if x is None else return [x]

Depending on your function, you may need to change the list test.

isinstance(x, list) # x is a list, or a sub-class of list
type(x) is list # x is a list, but not a sub-class
hasattr(x, '__iter__') # x looks more or less list-like
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,049
Latest member
Allen00Reed

Latest Threads

Top