patternpythonMinor
Nested array-to-dict transformation
Viewed 0 times
arraynesteddicttransformation
Problem
I'm looking to let people define arbitrarily nested lists of lists and return a random json document for them. Right now the assumption is that if you have a structure like this:
The desired document is:
This is my current solution:
as a one line fetishist, I feel like the middle line is beautiful, but I think the general hack of adding a dummy element to the end is hackish. Any thoughts on how to make this more elegant?
Also, not looking for deeply readable, this is just for my own private use and isn't going to spread out in any meaningful way, so I would just like to preempt the commentary about it not being readable.
Here's a more "readable" version:
[item1, item2, [item3, item4]]The desired document is:
{item1: value,
item2: {
item3: value,
item4: value
}
}This is my current solution:
def random_document(document_layout, type_, **kwargs):
document_layout.append("dummy_item")
doc = lambda l:{l[i]:doc(l[i+1]) if isinstance(l[i+1],list) else random_item(type_,**kwargs) for i in range(len(l)-1)}
return doc(document_layout)as a one line fetishist, I feel like the middle line is beautiful, but I think the general hack of adding a dummy element to the end is hackish. Any thoughts on how to make this more elegant?
Also, not looking for deeply readable, this is just for my own private use and isn't going to spread out in any meaningful way, so I would just like to preempt the commentary about it not being readable.
Here's a more "readable" version:
def random_document(document_layout, type_, **kwargs):
document_layout.append("dummy_item")
full_dict = {}
def internal_comprehension(document):
for i in range(len(document)-1):
if isinstance(document[i+1], list):
full_dict.update({document[i]: internal_comprehension(document[i+1])})
else:
full_dict.update({document[i]: random_item(type_, **kwargs)})
return internal_comprehension(document_layout)Solution
Your one-liner is too unreadable for my taste. Furthermore, neither version actually works.
The fundamental obstacle to elegance is that the problem requires you to look ahead one element to interpret how to handle the current element.
On the other hand, if you iterate through the
The fundamental obstacle to elegance is that the problem requires you to look ahead one element to interpret how to handle the current element.
def random_document(document_layout, type_, **kwargs):
def internal_comprehension(document):
full_dict = {}
for i in range(len(document)):
if isinstance(document[i], list):
# This item should have already been processed in a previous
# recursive call to internal_comprehension()
pass
elif i == len(document) - 1 or not isinstance(document[i+1], list):
# This item is an independent item
full_dict.update({document[i]: random_item(type_, **kwargs)})
else:
# Next item is a list, so create a level of nesting
full_dict.update({document[i]: internal_comprehension(document[i+1])})
return full_dict
return internal_comprehension(document_layout)On the other hand, if you iterate through the
document_layout backwards, then you don't have a look-ahead problem. Here's how it could look like:def random_document(document_layout, type_, **kwargs):
dict = {}
iter = reversed(document_layout)
for k in iter:
if isinstance(k, list):
dict[iter.next()] = random_document(k, type_, **kwargs)
else:
dict[k] = random_item(type_, **kwargs)
return dictCode Snippets
def random_document(document_layout, type_, **kwargs):
def internal_comprehension(document):
full_dict = {}
for i in range(len(document)):
if isinstance(document[i], list):
# This item should have already been processed in a previous
# recursive call to internal_comprehension()
pass
elif i == len(document) - 1 or not isinstance(document[i+1], list):
# This item is an independent item
full_dict.update({document[i]: random_item(type_, **kwargs)})
else:
# Next item is a list, so create a level of nesting
full_dict.update({document[i]: internal_comprehension(document[i+1])})
return full_dict
return internal_comprehension(document_layout)def random_document(document_layout, type_, **kwargs):
dict = {}
iter = reversed(document_layout)
for k in iter:
if isinstance(k, list):
dict[iter.next()] = random_document(k, type_, **kwargs)
else:
dict[k] = random_item(type_, **kwargs)
return dictContext
StackExchange Code Review Q#29557, answer score: 3
Revisions (0)
No revisions yet.