Is it possible to write a function that returns multiple values in a specific format?

Viewed 343

I'm writing a function that returns two values which will form the key-value pair of a dictionary. This function will be used to create a dictionary with dictionary comprehension. However, using dictionary comprehension the pair of values need to be provided in the format 'key: value'. To accomplish this, I have to call the function twice. Once for the key, and once for the value. For example,

sample_list = [['John', '24', 'M', 'English'], 
               ['Jeanne', '21', 'F', 'French'],
               ['Yuhanna', '22', 'M', 'Arabic']]

def key_value_creator(sample_list):
   key = sample_list[0]
   value = {'age': sample_list[1],
            'gender': sample_list[2], 
            'lang': sample_list[3]}

   return key, value

dictionary = {key_value_creator(item)[0]: \
              key_value_creator(item)[1] for item in sample_list}

As you can see, the function is called twice to generate values that can be generated in one run. Is there a way to return the values in a format that can be usable by the comprehension? If that is possible, the function need only be called once, as such:

dictionary = {key_value_creator(item) for item in sample_list}

As far as I have seen, other ways of returning multiple values is to return them in the form of a dictionary or list,

return {'key': key, 'value': value}
return [key, value]

but either way, to access them we will have to call the function twice.

dictionary = {key_value_creator(item)['key']: \
              key_value_creator(item)['value'] for item in sample_list}
dictionary = {key_value_creator(item)[0]: \
              key_value_creator(item)[1] for item in sample_list}

Is there a way to format these values so that we can send them to the dictionary comprehension statement in the format that it requires?

EDIT: Expected Output:

{ 'John': {'age': '24', 'gender': 'M', 'lang': 'English'}, 
'Jeanne': {'age': '21', 'gender': 'F', 'lang': 'French'}, 
'Yuhanna': {'age': '22', 'gender': 'M', 'lang': 'Arabic'}}
1 Answers

Just use the dict builtin function, expecting a sequence of (key, value) pairs as returned by your key_value_creator function and making a dict from those:

>>> dict(map(key_value_creator, sample_list))
{'Jeanne': {'age': '21', 'gender': 'F', 'lang': 'French'},
 'John': {'age': '24', 'gender': 'M', 'lang': 'English'},
 'Yuhanna': {'age': '22', 'gender': 'M', 'lang': 'Arabic'}}

Also works with a generator expression instead of map:

>>> dict(key_value_creator(item) for item in sample_list)

Or use a dictionary comprehension with a nested generator expression and tuple-unpacking:

>>> {k: v for k, v in (key_value_creator(item) for item in sample_list)}

Or without your key_value_creator function, just using a nested dictionary comprehension:

>>> {n: {"age": a, "gender": g, "lang": l} for n, a, g, l in sample_list}
Related