Python Forum

Full Version: Function - Return multiple values
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
Greeting!
I have to scan directories and find/process subdirectories.
Number of SubDirs not static.
I thought I could use a function but found I cannot "return" all the SubDirs.
I can print all of them but not return them.
I'm sure it is simple but I could not find a clear answer but I cannot find one.
def func(dir1):
    for ed1 in os.listdir(dir1) :
        echd_p = os.path.join(dir1,ed1)
        if os.path.isdir(echd_p) :
            return (echd_p)

fdp =  func(dir1)
print(type(fdp))   
print(fdp)  
Thank you.
This might be another way to go about solving the problem:

import os

def subdirectory_iterator (root_directory) :
	for root, dirs, files in os.walk(root_directory, topdown=False):
		for name in dirs:
			yield os.path.join(root, name)

for directory in subdirectory_iterator (dir1) :
	print (directory)
Thanks! I could return all the values by replacing 'return' with 'print'
def func(dir1):
    for ed1 in os.listdir(dir1) :
        echd_p = os.path.join(dir1,ed1)
        if os.path.isdir(echd_p) :
            print (echd_p)
What I'm interested in is how I can 'return' multiple values.
I have no idea how many Subdirs I'll get...
Just found I can make a list and pass it from a function....
Not sure if I tis good way to do it but it works.
def func(dir1):
    dir_l=[]
    for ed1 in os.listdir(dir1) :
        echd_p = os.path.join(dir1,ed1)
        if os.path.isdir(echd_p) :
            #print (echd_p)
            dir_l.append(echd_p)
    return(dir_l)

fdp =  func(dir1)
print(type(fdp))   
print(fdp)
Thank you!
Have a great rest of the day! Smile
Or a tuple
def func(a):
    return (a, a*a, a**3, a**4, a**5)

a, a2, a3, a4, a5 = func(5)

print(a, a2, a3, a4, a5)
Output:
5 25 125 625 3125
Or as a list using this form:
def func(a):
    return a, a*a, a**3, a**4, a**5  # <- Look Ma, no brackets!

a, a2, a3, a4, a5 = func(5)

print(a, a2, a3, a4, a5)
And if it makes sense to have a sequence you can use a generator and get the values one at a time.
def func(a, power):
    b = a
    for _ in range(power):
        yield b
        b *= a

print(list(func(5, 5)))
Output:
[5, 25, 125, 625, 3125]
Which way is "best" depends on your needs and tastes. In general I avoid functions that return multiple values, but sometimes it is the best solution.
Well, I do not know what that is but it looks impressive! Wink

Thank you!
(Jun-01-2021, 01:11 AM)tester_V Wrote: [ -> ]Thanks! I could return all the values by replacing 'return' with 'print'

No, you can't! All functions which don't have return or yield return None. Printing is not same as returning

>>> def my_func():
...     print('Hello world')
...
>>> print(my_func())
Hello world                    # what your function does
None                           # what your function returns
>>>
If you print from function then you give away flow control:

>>> value = my_func()         # I want to bind name to value returned by function
Hello world                   # as 'side-effect' it prints; there is no way to control it
>>> print(value)              # return value None is binded to name
None
This is your code written as a generator.
def func(dir1):
    """Generator that returns directories in dir1"""
    for ed1 in os.listdir(dir1) :
        echd_p = os.path.join(dir1, ed1)
        if os.path.isdir(echd_p):
            yield echd_p
 
for fdp in func(dir1):
    print(fdp)
In this case I think a generator works better than a returning a list.
Guys, I really appreciate your help!
I did not even use a function before.
Generators are very useful. Python is switching over to using them all over the place. It is time you learn how to use them.
Pages: 1 2