The data structure I am working with is a list of lists that is created by parsing a file. The depth of the list can vary. The list can have n Strings before its child-value begins.
My current example of this list of list looks something (this is already slightly formatted for better readability, also there can be different structures before and after it):
[['archive', 'Structures', [[
['set', 'Control', [['attribute', "'speed'", []], ['attribute', "'angle'", []], ['attribute', "'field'", []], ['attribute', "'cycle'", []], ['attribute', "'speed2'", []], ['attribute', "'field2'", []]]]
['part', 'Stage', [['attribute', "'Connection'", []], ['function', "StageOpen", []], ['attribute', "Resistance", []]]]
['archive', 'Field', [['attribute', "'Cycles'", []], ['attribute', "'Connection'", []], ['value', "'Field (Integer)'", []], ['attribute', "Poles", []], ['attribute', "'Inertia'", []], ['attribute', "'Magnet'", []]]]
['set', 'Load', [['value', "'testval'", []], ['attribute', "'coef'", []], ['attribute', "'inertia'", []]]]
]]
What I want to do is to search for a pair like ('set', 'Control')
or ('set', 'Load')
and get the list that is in the same record. For set/control
that would be:
[['attribute', "'speed'", []], ['attribute', "'angle'", []], ['attribute', "'field'", []], ['attribute', "'cycle'", []], ['attribute', "'speed2'", []], ['attribute', "'field2'", []]]]
From what I can see until now my program works, however I am not satisfied with it. I don't do recursions often and it's probably obvious that there is quite a potential for improvement:
class ParsedReader():
def __init__(self,parsed):
self.parsed=parsed
self.foundItem=[]
def reset(self):
self.foundItem=[]
@staticmethod
def compareFun(item,combo):
return all(elem in combo for elem in item)
def getChildrenByCombo(self, combo, depth=0, chain=None):
if chain is None:
chain=self.parsed
for item in chain:
if isinstance(item,str) or item == []:
continue
elif isinstance(item,list):
if self.compareFun(combo,item):
self.foundItem=item[self.getIndexOfClass(item,list)]
return item[self.getIndexOfClass(item,list)]
self.getChildrenByCombo(combo, depth+1, item)
return self.foundItem
@staticmethod
def getIndexOfClass(liste,klasse):
for cnt,obj in enumerate(liste):
if isinstance(obj,klasse):
return cnt
return -1
This is called by:
preader = ParsedReader(parsed)
sub_parts=preader.getChildrenByCombo(["set","control"])
#Do something
sreader.reset()
I am well aware recursions shouldn't use global variables, the exiting of the function is not clean, and so forth. However, it works. Yet, before I keep patching unnecessary things I'd be happy to receive a proper feedback on how this is to be done instead.