0

I was wondering how I can find values and its index on a list that may store another list in it.

I have taken a look at this post, but it does not work if there is a list inside of the list that is being searched.

Here is what I mean. Given the input:

["foo", ["f", "g"], "bar", "a", ["b", "c", "d"]]

Is it possible to find, for example, "f" and also return its index?

I know I could use recursion or something, but is there a faster and more elegant solution?

EDIT:

Also, the list may have more than one lists in it. For example, the list could be:

["foo", ["f", ["b", "c", "d"], "g"], "bar", "a"]

I need this in Python 3.

Monolith
  • 1,067
  • 1
  • 13
  • 29

3 Answers3

1

When dealing with arbitrarily nested data, it's hard to imagine a solution that's more elegant that a simple recursive generator. This will return all the indexes whether nested or not.

This will create a generator that find any element matching v and yields the index. If v is another list, it will use yield from to yield the results of calling the same generator on the sublist while keeping track of the list of parents.

def find(v, arr, parent = None):
    if parent is None:
        parent = []
    for idx, item in enumerate(arr):
        if item == v:                      # found an item
            yield parent + [idx]
        if isinstance(item, list):         # found a list, pass it back through the generator
            yield from find(v, item, parent + [idx])


l = ["foo", ["f", ["b", "c", "d", "a"], "g"], "bar", "a", "g"]

list(find('a', l))
# [[1, 1, 3], [3]]

list(find('g', l))
# [[1, 2], [4]]

list(find('x', l) # doesn't exist
# []
Mark
  • 90,562
  • 7
  • 108
  • 148
0

I think this is what you want!

let list = ["foo", ["f", "g"], "bar", "a", ["b", "c", "d"]];

for (let h = 0; h < list.length; h++) {
    if (Array.isArray(list[h])) {
        for (let i = 0; i < list[h].length; i++) {
            console.log(list[h][i], h, i);
        }
    } else {
        console.log(list[h], h);
    }
}

The above code will print this:

foo 0
f 1 0
g 1 1
bar 2
a 3
b 4 0
c 4 1
d 4 2
0

Here goes the python solution:

arr = ["foo", ["f", "g"], "bar", "a", ["b", "c", "d"]]

for h in arr:
    if isinstance(h,list):
        for i in h:
            print(i, arr.index(h), h.index(i))
    else:     
        print(h, arr.index(h))