suppose I have a dictionary
kwargs = {'key1': 1,
'key2': 2,
'key3list': [1,2,3,4]}
Where one of the values of any of the keys could be a list of integers, while the others would just be any object, in this case, an integer. I want to, in a single line (or in a couple at most) , put all the values of the keys into one tuple, unpacking all possible lists. Notice that by how the dictionary kwargs
is constructed, keys having a list will have the key ending with 'list'.
I came up with the following:
a = tuple(
[kwargs[key] if not key.endswith('list') else *kwargs[key] for key in kwargs.keys()]
)
However I get the error that I cannot unpack *kwargs[key]
here..
How could I fix this?
If you don't have to use list comprehension, a generator could be used:
def flat(l):
for k, v in l.items():
if type(v) == list:
for x in v:
yield x
else:
yield v
kwargs = {'key1': 1,
'key2': 2,
'key3list': [1,2,3,4]}
print(tuple(flat(kwargs)))
Output:
(1, 2, 1, 2, 3, 4)
Note that the dict
has no order so the resulting tuple can change based on the order that items()
returns the dictionary items.
It can be done using a nested list comp, but it's not pretty. One way is to wrap non-list items into lists, and then unpack the resulting 2D list.
kwargs = {
'key1': 1,
'key2': 2,
'key3list': [1, 2, 3, 4],
}
a = [u for v in
[val if key.endswith('list') else [val] for key, val in kwargs.items()]
for u in v]
print(a)
output
[1, 2, 1, 2, 3, 4]
I seriously recommend using traditional looping techniques here, don't try to do it all in a list comp. Eg,
a = []
for key, val in kwargs.items():
if key.endswith('list'):
a.extend(val)
else:
a.append(val)
print(a)
The above code can be written as
a = []
for key, val in kwargs.items():
meth = a.extend if key.endswith('list') else a.append
meth(val)
But even that is a bit too "clever", and less readable than the previous version.
We can make the code a little more general by ignoring the keys and testing if the current object is a list or not:
a = []
for val in kwargs.values():
if isinstance(val, list):
a.extend(val)
else:
a.append(val)
As Lutz Horn notes, this unpacking strategy is a little dangerous if the order of the output list is important, since traditionally in Python a plain dict doesn't necessarily retain insertion order. However in Python 3.6+, dicts do retain order, so this technique is safe, but it still makes me a little uncomfortable. ;)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.