Reputation: 2853
Given below is a sample multi list, that I am working with. Now I need to find the indices
of a given value if it appears anywhere in the list. For eg: for lis[0][2][2][1][0] which is 'span 1 2'
, I would like to get the index as [0,2,2,1,0]
.
lis = [['Root', ['span 1 6'], ['Nucleus', ['span 1 3'], ['Nucleus', ['span 1 2'], ['Nucleus', ['leaf 1'], ['text', "Specific knowledge "]], ['Satellite', ['leaf 2'], ['rel2par Elaboration'], ['text', 'required !_']]], ['Satellite', ['leaf 3'], ['rel2par Elaboration'], ['text', 'The tester is ']]], ['Satellite', ['span 4 6'], ['rel2par Elaboration'], ['Satellite', ['leaf 4'], ['rel2par Attribution'], ['text', 'For instance , the tester is aware!_']], ['Nucleus', ['span 5 6'], ['Nucleus', ['leaf 5'], ['rel2par Contrast'], ['text', 'that a!_']], ['Nucleus', ['leaf 6'], ['rel2par Contrast'], ['text', 'but ']]]]]]
I tried the following (modified from a web source).
from copy import copy
def scope2(word, list, indexes = None):
flag = 0
result = []
if not indexes:
indexes = []
for index, item in enumerate(list):
try:
current_index = indexes + [index]
result.append(current_index + [item.index(word)])
except ValueError:
pass
print item
print str(current_index) + ":::::" + str(list.index(item))
for stuff in item:
if type(stuff) == type([]):
flag =1
if flag==1:
indexes.append(index)
result.extend(scope2(word, item, copy(indexes)))
return result
Here the problem is that the index of sibling (lists at same level) also gets returned, but not always. Some sample outputs are like
for 0,2,3,1 it returns 0,2,3,1,0, similarly for lis[0][2][3][4][3][3] it returns 0,2,3,3,4,3,3
and so on. What can be the possible problem?
Upvotes: 0
Views: 172
Reputation: 38247
Here's an implementation of depth first and breadth first searching, not limited to strings. Would require a little reworking to search for a list or a tuple.
>>> l = [['Root', ['span 1 6'], ['Nucleus', ['span 1 3'], ['Nucleus', ['span 1 2'], ['Nucleus', ['leaf 1'], ['text', "Specific knowledge "]], ['Satellite', ['leaf 2'], ['rel2par Elaboration'], ['text', 'required !_']]], ['Satellite', ['leaf 3'], ['rel2par Elaboration'], ['text', 'The tester is ']]], ['Satellite', ['span 4 6'], ['rel2par Elaboration'], ['Satellite', ['leaf 4'], ['rel2par Attribution'], ['text', 'For instance , the tester is aware!_']], ['Nucleus', ['span 5 6'], ['Nucleus', ['leaf 5'], ['rel2par Contrast'], ['text', 'that a!_']], ['Nucleus', ['leaf 6'], ['rel2par Contrast'], ['text', 'but ']]]]]]
>>> def depth_first(term,data):
... for i, item in enumerate(data):
... if isinstance(item,Sequence) and not isinstance(item,basestring):
... r = depth_first(term,item)
... if not r is None:
... return [i] + r
... else:
... if item == term:
... return [i]
...
>>> def breadth_first(term,data):
... later = []
... for i, item in enumerate(data):
... if isinstance(item,Sequence) and not isinstance(item,basestring):
... later.append((i,item))
... else:
... if item == term:
... return [i]
... for i, item in later:
... r = breadth_first(term,item)
... if not r is None:
... return [i] + r
>>> depth_first('span 1 2',l)
[0, 2, 2, 1, 0]
>>> breadth_first('span 1 2',l)
[0, 2, 2, 1, 0]
Upvotes: 1
Reputation: 368904
>>> def trail(word, lst):
... if word in lst:
... return [lst.index(word)]
... for i, x in enumerate(lst):
... if not isinstance(x, list):
... continue
... ret = trail(word, x)
... if ret is not None:
... return [i] + ret
...
>>> trail('span 1 2', lis)
[0, 2, 2, 1, 0]
>>> lis[0][2][2][1][0]
'span 1 2'
>>> trail('no such string', lis)
>>>
Upvotes: 2