Use return value in another function

Hi community,

I ran into the problem of putting the return of one function into another. Maybe someone could recommend any solution?

Let me describe a situation:

Function 1:

def get_list(*key):
    headers_list = {
        "Accept": "application/json",
    }

    getlst = requests.get("https://api.example.com/v3.0/api/Menu/List", headers = headers_list)
    getlst_res = getlst.json()

    for item in getlst_res:
        print(item[key[0]] + ' = ' + item[key[1]])

Usage of the function 1:

get_list('name','code')

Output of the function 1:

2N = 2N
360 = ZW
70MAI = MQ
ARMR = AR

Function 2:

def get_id(*key):
    headers_id = {
        "Accept": "application/json",
    }

    pid = requests.get(f"https://api.example.com/v3.0/api/Menu/Items?itemCode={key[0]}", headers = headers_id)
    pid_res = pid.json()

    for item in pid_res:
        print(f'Item id: {item[key[1]]}')

Usage of the function 2:

get_id('2N', 'id')

Output of the function 2:

Item id: 1226569
Item id: 1226571
Item id: 1218108
Item id: 1218111
Item id: 1227409

In the “Output of the function 2” you could see only item ids which were assigned to “code” - “2N”.

Expected result:

In the “Output of the function 1” we get more “codes”: “ZW”, “MQ”, “AR”.

The main goal is to get the item ids of all codes (“2N”, “ZW”, “MQ”, “AR”) as the single output.
(Not only “2N” item ids, but as well “ZW”, “MQ” and “AR”)

Thanks in advance :slight_smile:

I think I understand and would first like to clarify:

You would like to feed this data stream…

'2N', 'ZW', 'MQ', 'AR'

…into this function?

get_id(*key)

Answer:

Functions can act like variables. In other words, they can “represent” a value that is passed to another function, so you can do things like nesting function calls:

function2(function1(arg))

To nest your function calls like this, there needs to be a return item[key[1]] In the code of

def get_list(*key):

Solution:

In the posted code, there is only print() and no return. Add a return.

After you have the codes returning into your main thread, you need to modify one or both functions so that get_list(*key): can handle more than one ‘code’ or iterate through the returned values of get_list(*key): with a for loop like this…

for item in get_list('name','code'):
    get_list(item)  #simplified version of the posted function

Here’s a simple example of a nested function call (get-list() is called inside of the print() function). This is simpler than the posted process and shows the execution clearly since the other actions are not included.
NOTE: I also made this example because I can’t safely run the posted code. It’s not worth the security risk of retrieving unknown objects from unknown web sites, no matter how harmless it looks.

def get_list(*key):
    item = dict(A=1,B=2,C=3)
    return item[key[0]],item[key[1]]

print(get_list('A','B'))

Minor item:

You can simplify the print() statement by using commas instead of the string “math” and adding (padding) spaces inside of quotes:

print(item[key[0]], '=', item[key[1]])

    instead of

print(item[key[0]] + ' = ' + item[key[1]])
1 Like

Just to fix the terminology and meaning of words:

  • For the demonstrated use, functions do not need to be objects (like all other objects in python). So to avoid confusion it is best to remove the unrelated first part of the sentence.
  • “function nesting” is something different, please see below. In your example you just call function1 and pass its return value as an argument to function2. If we would like to find a fancy name for this we could use something like “chained calling of functions”?[1]

Nested functions:

def function1():
    def function2():
        pass

In the example above function2 is an inner function or a nested function. This concept is useful for example when you are creating decorators.


The common way how to write the print in Python would be using an f-string:

print(f'{item[key[0]]} = {item[key[1]]}')

The advantages which come to my mind:

  • Not limited to print(). We are creating a string.
  • We can start adding formatting (padding etc.) right away.
  • For people used to f-strings this is a single flow of string, not interrupted by commas or + operators.

  1. Like Method chaining - Wikipedia ↩︎

2 Likes

Thank you @mlgtechuser and @vbrozik for your replies!

I have changed a bit my first function:

def get_list(*key):
    headers_list = {
        "Accept": "application/json",
    }

    getlst = requests.get("https://api.eexample.com/v3.0/api/Menu/List", headers = headers_list)
    getlst_res = getlst.json()

    for item in getlst_res:
        print(f'{item[key[0]]} = {item[key[1]]}')
    return f'{item[key[0]]} = {item[key[1]]}'

print(get_list('code'))

But I get an error: IndexError: tuple index out of range (When I specify two keys: ‘name’ and ‘code’ - everything works fine: print(get_list(‘name’,‘code’)))

Is it a must to specify all keys in the “print” or my “function2”? ( In this example it’s print(get_list(‘code’)) )

What if I need only one key value, let’s say “code”?

I have tried to specify only one key as a return value: return item[key[1]] of the function 1, but got the same error massage.

I’m wondering did I understood you correctly and did I change my function 1 correctly or maybe I have missed something important.

#----------------------------------------------------------------------------------------------------------------------------------------#

Do I understand correctly that if I want to use all “code” values from function 1 in my function 2 as a key[0], I should use for loop when sending a “GET” request inside function 2:

def get_id(*key):
    headers_id = {
        "Accept": "application/json",
    }

    for item in get_list('code'):
         pid = requests.get(f"https://api.example.com/v3.0/api/Menu/Items?itemCode={key[0]}", headers = headers_id)
         pid_res = pid.json()

         for item in pid_res:
            print(f'Item id: {item[key[1]]}')

Or should I use for loop outside the function 2?

When you get an error, don’t just look at the error message at the end. Copy and paste the full error, starting from the beginning “Traceback …” so we can see the whole thing.

My wild guess is that you get this error when you only pass one argument to the function.

You have a parameter called “key” (note that the name is singular) which will collect zero or more arguments passed to the function.

So the variable “key” will be a tuple of zero or more items:

  • if you call get_list(), the variable key will equal ().
  • if you call get_list("a"), key will equal (“a”,)`.
  • if you call get_list("a", "bb"), key will equal (“a”, “bb”)`.

And so on.

This is fine so far. But then you have two lines of code that try to retrieve the first and second items from “key”:

key[0]  # First item.
key[1]  # Second item.

Yes, I know it’s weird that Python uses 0 for the first position and 1 for the second :slight_smile:

But if key has no items, or only 1 item, then one or both of those attempted retrievals will fail with

IndexError: tuple index out of range

just as you are reporting.

1 Like

True enough. The reference to objects was a bit off-topic, so I’ve removed it.

“function nesting” is something different

Again, this is a true enough statement to stand. This WIkipedia article expresses the same “function defined inside of a function” definition. However, the reply above is a valid use of the general term “nested”. (I know, I know…this a technical scenario and “nested function” is already defined as something specific. :stuck_out_tongue_winking_eye: )

Clear terms are important in technical activity, so the clarification is appreciated. The same Wikipedia article calls the parent function the “enclosing function”, so “A function defined inside of a function” is perhaps better referred to as an “enclosed function”. Even better would be “embedded function” but that ship has probably sailed. ‘Inner’ and ‘Outer’ are clean, short, and very appealing. :+1:

Accordingly, I’ve also revised my post to use the term nested function call to refer to function2( function1() ). This time I did some searching before posting and the term seems to be very accurate. But if any further refinement seems needed, let’s continue that discussion via PM or in a separate topic so that this topic can stay focused on the OP person and their question. :email:

Regarding the different ways to compose a `print()` statement...

…that’s a very open-ended subject. I propose that we create a “Coding Styles” subcategory of ‘Users’ where we can address these situations without adding (potentially off-topic) traffic to a basic request for help. Often the OP just wants to finish his "Hello World" or “Hello Solar System” exercise and understand how that one way to do it works, and why that one way works before considering alternative methods or styles. ‘How to Help’ is another valuable subcategory that’s worth considering so we can share and discuss best practices. All will benefit, especially new members who ask for help.

2 Likes