Theo
Theo

Reputation: 31

python list as index for a nested list

I have the following two lists:

l1 = [2, 3, 2]
l2 = [0, [0, 1], [0, 1, 0, [0, 1, [0, 0]]]]

How can I use the first list as a tree index, in order to append an item to the second list, like doing

l2[2][3][2].append(0) 

Upvotes: 1

Views: 96

Answers (5)

R.Sharp
R.Sharp

Reputation: 316

For some strange reason, I immediately thought of a recursive routine, but essentially it does does what Kostas is doing, I just find it easier to follow :

def tree_appender(tree, location, thing):
    sub_tree_index = location.pop(0)
    if len(location) > 0:
        tree_appender(tree[sub_tree_index], location, thing)
    else:
        tree[sub_tree_index].append(thing)
    return


>>> l1 = [2, 3, 2]
>>> l2 = [0, [0, 1], [0, 1, 0, [0, 1, [0, 0]]]]
>>> python_file.tree_appender(l2, l1, "dave")
>>> l2
[0, [0, 1], [0, 1, 0, [0, 1, [0, 0, 'dave']]]]

It will fail of course if l1 was [0] for example as l2[0] is an int not a list. You could test for that and turn whatever is about to have something appended to it into a list if that was likely to be desired.

Upvotes: 0

Tim Fuchs
Tim Fuchs

Reputation: 1191

There is no standard way to do that, but this will work:

from functools import reduce
from operator import getitem

def tree_index(tree, index):
    return reduce(getitem, index, tree)

tree_index(l2, l1).append(0)

As a bonus, the tree_index function also works for dictionaries and any other mappings. For example:

>>> adjs = {'apple': ['red', 'green'], 'swallow': ['african', 'european'] }
>>> tree_index(adjs, ['apples', 0])
'red'

On the other hand, tree_index will not work for assignments. This will not work:

tree_index(l2, [1,1]) = 33 # throws SyntaxError

In order to assign to tree indices you need another function or partial indexing:

tree_index(l2, [1])[1] = 33

Upvotes: 3

awesoon
awesoon

Reputation: 33651

You could use reduce function:

In [1]: l1 = [2, 3, 2]

In [2]: l2 = [0, [0, 1], [0, 1, 0, [0, 1, [0, 0]]]]

In [3]: from functools import reduce

In [4]: reduce(lambda l, i: l[i], l1, l2)
Out[4]: [0, 0]

In [5]: l2[2][3][2]
Out[5]: [0, 0]

Upvotes: 1

YiFei
YiFei

Reputation: 1802

Do this only if you know what you're doing:

l1 = [2, 3, 2]
l2 = [0, [0, 1], [0, 1, 0, [0, 1, [0, 0]]]]

str1=repr(l1)
str1=str1.replace(', ','][') # str1=[2][3][2]
eval(repr(l2)+str1) # or var=exec(repr(l2)+str1)

Upvotes: 0

Kostas Pelelis
Kostas Pelelis

Reputation: 1342

This should work

def tree_append(tree, index_list', val=None):
    for index in index_list:
        tree = tree[index]
    tree.append(val)

l1 = [2, 3, 2]
l2 = [0, [0, 1], [0, 1, 0, [0, 1, [0, 0]]]]

tree_append(l2, l1, val=0)

>> l2
[0, [0, 1], [0, 1, 0, [0, 1, [0, 0. 0]]]]

Upvotes: 1

Related Questions