views:

362

answers:

4

Hello,

I have a function that has several outputs, all of which "native", i.e. integers and strings. For example, let's say I have a function that analyzes a string, and finds both the number of words and the average length of a word.

In C/C++ I would use @ to pass 2 parameters to the function. In Python I'm not sure what's the right solution, because integers and strings are not passed by reference but by value (at least this is what I understand from trial-and-error), so the following code won't work:

def analyze(string, number_of_words, average_length):

    ... do some analysis ...

    number_of_words = ...    
    average_length = ...

If i do the above, the values outside the scope of the function don't change. What I currently do is use a dictionary like so:

def analyze(string, result):

    ... do some analysis ...

    result['number_of_words'] = ...    
    result['average_length'] = ...

And I use the function like this:

s = "hello goodbye"
result = {}
analyze(s, result)

However, that does not feel right. What's the correct Pythonian way to achieve this? Please note I'm referring only to cases where the function returns 2-3 results, not tens of results. Also, I'm a complete newbie to Python, so I know I may be missing something trivial here...

Thanks

A: 

If you need to use method arguments in both directions, you can encapsulate the arguments to the class and pass object to the method and let the method use its properties.

Jakub Šturc
Except in this particular case, because in Python, integers and strings are immutable.
mipadi
+14  A: 

python has a return statement, which allows you to do the follwing:

def func(input):
    # do calculation on input
    return result

s = "hello goodbye"
res = func(s)       # res now a result dictionary

but you don't need to have result at all, you can return a few values like so:

def func(input):
    # do work
    return length, something_else         # one might be an integer another string, etc.

s = "hello goodbye"
length, something = func(s)
SilentGhost
This is what I was looking for, thanks!
Roee Adler
+3  A: 

If you return the variables in your function like this:

def analyze(s, num_words, avg_length):
    # do something
    return s, num_words, avg_length

Then you can call it like this to update the parameters that were passed:

s, num_words, avg_length = analyze(s, num_words, avg_length)

But, for your example function, this would be better:

def analyze(s):
    # do something
    return num_words, avg_length
jcoon
+1  A: 

In python you don't modify parameters in the C/C++ way (passing them by reference or through a pointer and doing modifications in situ).There are some reasons such as that the string objects are inmutable in python. The right thing to do is to return the modified parameters in a tuple (as SilentGhost suggested) and rebind the variables to the new values.

Sergio