user3477470
user3477470

Reputation: 53

python return two dictionaries

I am trying to return two dictionaries. person_to_friends and person_to_networks are given functions, and profiles_file is a text file. What I wrote is:

def load_profiles(profiles_file, person_to_friends, person_to_networks):
    """
    (file, dict of {str : list of strs}, dict of {str : list of strs}) -> NoneType
    Update person to friends and person to networks dictionaries to include
    the data in open file.
    """
    profiles_file = open('data.txt', 'r')
    person_to_friends = person_to_friends(profiles_file)
    person_to_networks = person_to_networks(profiles_file)    
    return person_to_friends, person_to_networks

This only gives me person_to_friends dictionary..Could anyone can help this problem?

What I want to return is

{person_to_friends}

{person_to_networks}

Upvotes: 1

Views: 14760

Answers (5)

samuel161
samuel161

Reputation: 281

maybe you can try

class temp(a, b):
    return dict(a=a, b=b)

Upvotes: 0

x3al
x3al

Reputation: 586

You can return only one value (this value can be a tuple, as in your case). However, you can yield as much values as you need:

def load_profiles(profiles_file, person_to_friends, person_to_networks):
    """
    (file, dict of {str : list of strs}, dict of {str : list of strs}) -> NoneType
    Update person to friends and person to networks dictionaries to include
    the data in open file.
    """
    profiles_file = open('data.txt', 'r')
    person_to_friends = person_to_friends(profiles_file)
    person_to_networks = person_to_networks(profiles_file)    
    yield person_to_friends  # you can do it without temp variable, obv.
    yield person_to_networks

The difference is that with yield statement you don't construct a temporary tuple just to return two results at once. However, getting the values out of your "function" (that became a generator) will be slightly more difficult:

profiles = load_profiles(your args)

will not actually run your function at all, it just initializes a generator. To actually get values, you'll need to:

person_to_friends = next(profiles)
person_to_networks = next(profiles)

or just do a loop:

for result in load_profiles(your args):
    do_something_with_your_dictionaries

So your function will return one value: the initialized generator object. Iterating over it in a loop (it can be for loop, map, filter, list(your_generator) or something else) or just calling next(your_generator) will give you both dictionaries you actually need.

Upvotes: 1

Peter Gibson
Peter Gibson

Reputation: 19554

Your docstring states that the function parameter person_to_friends is a

dict of {str : list of strs}

But then you call it as though it were a function and overwrite it with the result:

 person_to_friends = person_to_friends(profiles_file)

Is this a mistake in the docstring, or the code?

Possibly you are masking the real function definition by having a locally defined variable of the same name (ie the parameter). In general it is bad practice to override a variable of one type (eg function) with another vastly different type (eg dict) - although there are exceptions to this.

Upvotes: 0

Akavall
Akavall

Reputation: 86178

The way you are returning two dictionaries is fine, something funny must be going on in the other parts of the code, if your remove them, everything works fine:

def load_profiles():
    person_to_friends = {'a' : 1}
    person_to_networks = {'b' : 2}    
    return person_to_friends, person_to_networks

Result:

>>> load_profiles()
({'a': 1}, {'b': 2})
>>> dict_1, dict_2 = load_profiles()
>>> dict_1
{'a': 1}
>>> dict_2
{'b': 2}

Upvotes: 0

dursk
dursk

Reputation: 4445

Simply do:

return (person_to_friends, person_to_networks)

and when you call the function you need to unpack the return value:

person_to_friends, person_to_networks = load_profiles(var1, var2, var3)

Upvotes: 7

Related Questions