Reputation: 13
new programmer here. Forgive any occasional idiocy.
I'm trying to write a little function that returns the deepest list in an (arbitrarily large) nested list. The sublists contain tuples, and strings as well.
Example:
L = ['o', ([], [(1, 'V'), (-1, 'C')]), ['o', ['o', (['prefers'], [(1, 'D'), (1, 'D'), (-1, 'V')]), ['o', (['the'], [(1, 'N'), (-1, 'D')]), (['beer'], [(-1, 'N')])]], ['o', (['the'], [(1, 'N'), (-1, 'D')]), (['king'], [(-1, 'N')])]]]
I realize this is insanely hard to parse. Which is um, why I want the machine to do it.
(In case you're wondering, I'm a linguist, and this list defines the derivation tree of a sentence in a minimalist grammar.) What I want is to return the most deeply embedded list, in this case ['o', (['the'], [(1, 'N'), (-1, 'D')]), (['beer'], [(-1, 'N')])]]. Here's what I've tried (among other things):
def get_deepest(L):
is_list = True
while is_list == True:
for e in L:
is_list = any(isinstance(e,list) for e in L)
get_deepest(e)
return e
This hits the recursion limit. Any pointers? I've been struggling with this for a few days.
Thanks.
Upvotes: 1
Views: 996
Reputation: 1549
Here's my solution. Your get_deepest()
call was not returning anything back, so there is a logical error, and it keeps going deeper.
Lst = ['o', ([], [(1, 'V'), (-1, 'C')]), ['o', ['o', (['prefers'], [(1, 'D'), (1, 'D'), (-1, 'V')]), ['o', (['the'], [(1, 'N'), (-1, 'D')]), (['beer'], [(-1, 'N')])]], ['o', (['the'], [(1, 'N'), (-1, 'D')]), (['king'], [(-1, 'N')])]]]
def get_dpst(L, maxdepth):
deepest_tup = (L, maxdepth)
for e in L:
is_list = any(isinstance(e,list) for e in L)
if is_list:
tup = get_dpst(e, maxdepth+1)
if tup[1] > deepest_tup[1]:
deepest_tup = tup
return deepest_tup
def get_deepest(L):
tup = get_dpst(L, 0)
return tup[0]
def printlist(lst):
print '[%s]' % ', '.join(map(str, lst))
printlist(get_deepest(Lst))
Or define a function within a function.
Lst = ['o', ([], [(1, 'V'), (-1, 'C')]), ['o', ['o', (['prefers'], [(1, 'D'), (1, 'D'), (-1, 'V')]), ['o', (['the'], [(1, 'N'), (-1, 'D')]), (['beer'], [(-1, 'N')])]], ['o', (['the'], [(1, 'N'), (-1, 'D')]), (['king'], [(-1, 'N')])]]]
def get_deepest(L):
def get_dpst(L, maxdepth):
deepest_tup = (L, maxdepth)
for e in L:
is_list = any(isinstance(e,list) for e in L)
if is_list:
tup = get_dpst(e, maxdepth+1)
if tup[1] > deepest_tup[1]:
deepest_tup = tup
return deepest_tup
tup = get_dpst(L, 0)
return tup[0]
def printlist(lst):
print '[%s]' % ', '.join(map(str, lst))
printlist(get_deepest(Lst))
Upvotes: 0
Reputation:
L = ['o', ([], [(1, 'V'), (-1, 'C')]), ['o', ['o', (['prefers'], [(1, 'D'), (1, 'D'), (-1, 'V')]), ['o', (['the'], [(1, 'N'), (-1, 'D')]), (['beer'], [(-1, 'N')])]], ['o', (['the'], [(1, 'N'), (-1, 'D')]), (['king'], [(-1, 'N')])]]]
max_depth = -1
deepest_list = None
def get_deepest(L,depth=0):
global max_depth, deepest_list
if depth > max_depth:
max_depth = depth
deepest_list = L
for x in L:
if isinstance(x,list):
get_deepest(x,depth+1)
get_deepest(L)
print deepest_list
This code is hacked together, and there's bound to be a way to do it without globals. By the way, I think recursion is okay for moderately sized problems here.
Upvotes: 0
Reputation: 1008
Mimick the recursion stack by using a stack yourself.
tovisit = [ L ]
current_deepest = None
while tovisit != []:
v = tovisit.pop()
for e in v:
tovisit.append(e)
You'll need to add your own logic here (your current function is wrong, you return e while out of the for loop).
Upvotes: 1