-3

The following function prints installed apps from a server.

def getAppNames():
    for app in service.apps:
        print app.name   

It works absolutely fine and it prints a list of installed apps like so:

App A

App B

App C

App D

App E

App F

However when I change the "print" to a "return", all I get is "App A". I have seen similar questions on this but I cant find a solution and have explored different methods. Basicly I require the return function like the print function, I would appreciate any help. Thanks.

Conor
  • 17
  • 1
  • 2
  • 5
  • The first element in service.apps is returned on the first iteration and then the function stops. You might be looking for `def getAppNames(): return service.apps` – Tim May 09 '14 at 13:02
  • 1
    You might want to read up some basics. Do you know what a `return` does? – keyser May 09 '14 at 13:23

5 Answers5

8

The return statement causes your function to immediately exit. From the documentation:

return leaves the current function call with the expression list (or None) as return value.

The quick fix is to save the names in a temporary list, then return the list:

def getAppNames():
    result = []
    for app in service.apps:
        result.append(app.name)
    return result

Since this is such a common thing to do -- iterate over a list and return a new list -- python gives us a better way: list comprehensions.

You can rewrite the above like this:

def getAppNames:
    return [app.name for app in service.apps]

This is considered a "pythonic" solution, which means it uses special features of the language to make common tasks easier.

Another "pythonic" solution involves the use of a generator. Creating a generator involves taking your original code as-is, but replacing return With yield. However, this affects how you use the function. Since you didn't show how you are using the function, I'll not show that example here since it might add more confusion than clarity. Suffice it to say there are more than two ways to solve your problem.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
2

There are two solutions:

def getAppNames():
    return [app.name for app in service.apps]

or

def getAppNames():
    for app in service.apps:
        yield app.name

Unlike return, yield will stay in the loop. This is called a "generator" in Python. You can then use list() to turn the generator into a list or iterate over it:

for name in getAppNames():
    ...

The advantage of the generator is that it doesn't have to build the whole list in memory.

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
  • 2
    There is at least one more (un-pythonic) solution, which is to keep the loop and append each name to a list, then return the list. This might be a simpler concept for a new programmer to grasp. – Bryan Oakley May 09 '14 at 13:12
1

You should read basic docs about Python :)

try this:

def getAppNames():
    return [app.name for app in service.apps]
Dmitry Loparev
  • 462
  • 2
  • 9
1

After a return statement the function "ends" - it leaves the function so your for loop actually does only a single iteration.

To return a list you can do -

return [app for app in service.apps]

or just -

return service.apps
Tom Ron
  • 5,906
  • 3
  • 22
  • 38
0

The first time you hit a return command, the function returns which is why you only get one result.

Some options:

  • Use 'yield' to yield results and make the function act as an generator
  • Collect all the items in a list (or some other collection) and return that.
Community
  • 1
  • 1
Jon Cage
  • 36,366
  • 38
  • 137
  • 215