Search code examples
pythonfunctioninputoutputiterable-unpacking

Python syntax for returning both a single unpacked value or multiple packed values from a sequence


this might be a great pythonic heresy, but I'm looking for syntax that replicates the behavior of the code below, without using both the return and the yield clause in the function "sign" (edit this syntax does not in fact produce the below outputs).

def sign_inner(num):
    return 1 if num>0 else -1 if num<0  else 0

def sign(*nums):
    if len(nums)==1:
        return sign_inner(nums[0])
    for num in nums:
        yield sign_inner(num)

The idea is to output a non-iterable object when a single input is given and an iterable object when multiple inputs are given. Here's an example of how it should behave:

a = sign(3)
a
>>> 1
a, b = sign(3, -5)
a
>>> 1
b
>>> -1

I don't mind constructing a temporary sequence inside the function so long as it is automatically unpacked when returned. Ideally the sign function would look something like this:

def sign(*nums):
    for num in nums:
        yield sign_inner(num)

But yield creates a generator object and in the case of a single input one must add a comma or brackets to unpack it:

a, = sign(3)
a
>>> 1

whereas without the comma:

a = sign(3)
a
>>> <generator object sign at 0x____________>

Solution

  • def sign_inner(num):
        return 1 if num>0 else -1 if num<0  else 0
    
    def sign(*nums):
        results = []
        for num in nums:
            results.append(sign_inner(num))
        return results[0] if len(results)==1 else results 
    
    A = sign(5,1,-5)
    B = sign(5)
    a, b, c = sign(5,1,-5)
    
    print(A)
    print(B)
    print (a)
    print (a,b,c)
    

    Output:

    >> [1,1,-1]
    >> 1
    >> 1
    >> 1  1  -1