Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Return tuple or list?

Tags:

python

I have a method that returns either a list or a tuple. What is the most pythonic way of denoting the return type in the argument?

def names(self, section, as_type=()):
    return type(as_type)(([m[0] for m in self.items(section)]))
like image 756
noobzie Avatar asked Nov 16 '11 21:11

noobzie


3 Answers

Return whatever the caller will want most of the time. If they will want to be able to sort, remove or delete items, etc. then use a list. If they will want to use it as a dictionary key, use a tuple. If the primary use will be iteration, return an iterator. If it doesn't matter to the caller, which it won't more often than you might think, then return whatever makes the code the most straightforward. Usually this will be a list or an iterator.

Don't provide your own way to convert the output to a given type. Python has a perfectly simple way to do this already and any programmer using your function will be familiar with it. Look at the standard Python library. Do any of those routines do this? No, because there's no reason to.

Exception: sometimes there's a way to get an iterator or a list, even though it is easy to convert an iterator to a list. Usually this capability is provided as two separate functions or methods. Maybe you might want to follow suit sometimes, especially if you could implement the two alternatives using different algorithms that provide some clear benefit to callers who want one or another.

like image 160
kindall Avatar answered Oct 24 '22 05:10

kindall


The pythonic way would be not to care about the type at all. Return a tuple, and if the calling function needs a list, then let it call list() on the result. Or vice versa, whichever makes more sense as a default type.

Even better, have it return a generator expression:

def names(self, section):
    return (m[0] for m in self.items(section))

Now the caller gets an iterable that is evaluated lazily. He then can decide to iterate over it:

for name in obj.names(section):
    ...

or create a list or tuple from it from scratch - he never has to change an existing list into a tuple or vice versa, so this is efficient in all cases:

mylist = list(obj.names(section))
mytuple = tuple(obj.names(section))
like image 28
Tim Pietzcker Avatar answered Oct 24 '22 03:10

Tim Pietzcker


Keep it simple:

def names(self, section):
    """Returns a list of names."""
    return [m[0] for m in self.items(section)]

If the caller wants a tuple instead of a list, he does this:

names = tuple(obj.names(section))
like image 42
yak Avatar answered Oct 24 '22 03:10

yak