Can anyone help me figure the list comprehension way of producing following output -
Let given list be -
results = [
{"id": 1, "name": "input"},
{"name": "status", "desc": "Status"},
{"name": "entity", "fields": [
{"id": 101, "name": "value"},
{"id": 102, "name": "address"}]
}
]
And I am looking for output in the form of list. The code to get the output is:
output = []
for eachDict in results:
if "fields" in eachDict:
for field in eachDict["fields"]:
output.append(eachDict["name"]+"."+field["name"])
else:
output.append(eachDict["name"])
Thus the output using above code is -
['input', 'status', 'entity.value', 'entity.address']
Is it possible to get similar output using if else nested for loops in list Comprehension?
I am having trouble trying to get access to that inner for loop in if condition of list Comprehension
My attempt -
output = [eachDict["name"]+"."+field["name"] for field in eachDict["fields"] if "fields" in eachDict else eachDict["name"] for eachDict in results]
One way to transform your code into workable code would be to make the inner loop produce lists, and then flatten the result afterward.
sum(([d['name'] + '.' + f['name'] for f in d['fields']]
if d.get('fields') else [d['name']] for d in results), [])
A list comprehension has a fixed number of (nested) loops. So must have two loops here, one over the top-level dictionaries, and one over the fields
. The trick is to produce one iteration in the nested loop if there are no fields:
[d['name'] + fieldname
for d in results
for fieldname in (
('.' + sub['name'] for sub in d['fields']) if 'fields' in d else
('',))
]
The for fieldname
loop loops either over the names of the fields
sub-directories (with '.'
prefixed), or over a tuple with just a single empty string in it.
Note that this isn't actually all that readable. I'd delegate producing the fieldname loop to a helper generator function to improve that:
def fieldnames(d):
if 'fields' in d:
for sub in d['fields']:
yield '.' + sub['name']
else:
yield ''
[d['name'] + fieldname for d in results for fieldname in fieldnames(d)]
Demo:
>>> def fieldnames(d):
... if 'fields' in d:
... for sub in d['fields']:
... yield '.' + sub['name']
... else:
... yield ''
...
>>> [d['name'] + fieldname for d in results for fieldname in fieldnames(d)]
['input', 'status', 'entity.value', 'entity.address']
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.