Reputation: 68486
I have the following function:
def create_list_from_dict1(mydict):
output = []
for k, v in openint_dict.items():
output.append( (k, v['field1'], v['field2'], v['field3']) )
return output
Essentially, it flattens the dictionary, so that I can perform sorting on one of the fields of the tuple in the returned list.
I don't like the fact that I am having to 'hard code' the field names of the value dictionary ('field1'
, ..., 'fieldN'
), and I want a more pythonic and elegant way of doing this so that this function works for all dictionaries that contain a fixed structure (non-nested) dictionary as its values.
I imagine that I will have to use **kwargs
and/or a lambda
function, as well as list comprehension. What would be the most pythonic way to write this function?
Upvotes: 6
Views: 19535
Reputation: 114588
Python dict
s have keys()
and values()
methods to get a list of the keys and values. If order of the fields is not important:
[(k,) + tuple(v.values()) for k, v in mydict.items()]
If the ordering of the values does matter:
[(k,) + tuple(v[i] for i in sorted(v)) for k, v in mydict.itemd()]
Note that the second option would be identical to the first without the call to sorted()
. The order depends on how things were added to the subdict, so you should use the second option as much as possible.
Upvotes: -1
Reputation: 122
I think this would be pythonic:
[(k, v) for k, v in dict_data.items()]
Upvotes: 0
Reputation: 18668
def create_list_from_dict1(mydict):
return [tuple([k]+list(v.values())) for k,v in openint_dict.items()]
doesn't use the fields' names and produces the same result.
In Python 3.5, you can just type (because starred expressions are allowed everywhere):
def create_list_from_dict1(mydict):
return [(k,*v.values()) for k,v in openint_dict.items()]
Upvotes: 0
Reputation: 122157
This might solve your problem:
def create_list_from_dict1(mydict):
return [
(key,) + tuple(v for _, v in sorted(val.items()))
for key, val in sorted(mydict.items())
]
This assumes that:
key
for sorted
);Note the use of .items
in both inner and outer loops to sort both by key (two-tuples are sorted on the first element, with the second only used to break ties) and the conventional _
identifier for "we won't be using this any more".
In use:
>>> create_list_from_dict1({
'hello': {'foo': 1, 'bar': 2, 'baz': 3},
'world': {'foo': 4, 'bar': 5, 'baz': 6},
})
[('hello', 2, 3, 1), ('world', 5, 6, 4)]
Upvotes: 4
Reputation: 10145
You can do it like this:
fields = ("field1", "field2", "field3")
output = [[k] + [mydict[k].get(x) for x in fields] for k in mydict]
In that code we iterate dict keys and add them with selected subset of second-level dictionaries values.
Upvotes: 5
Reputation: 376
If order doesn't matter...
def create_list_from_dict1(mydict):
output = []
for k, v in openint_dict.items():
fields = [value for key, value in v.items()]
output.append( tuple([k] + fields )
return output
If order matters you either need to do as you did and call out the fields specifically...or you need to used an OrderedDict
for the sub-dicts.
Upvotes: 0