Python: Return tuple or list?

后端 未结 3 800
被撕碎了的回忆
被撕碎了的回忆 2021-02-20 03:33

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_typ         


        
相关标签:
3条回答
  • 2021-02-20 03:51

    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))
    
    0 讨论(0)
  • 2021-02-20 04:03

    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.

    0 讨论(0)
  • 2021-02-20 04:12

    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))
    
    0 讨论(0)
提交回复
热议问题