Reputation: 53
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
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
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
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
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