访问嵌套列表元素,运行时已知深度

时间:2016-11-26 18:23:43

标签: python python-2.7 list

我想写一个名为foo的嵌套列表中的元素,但嵌套深度和索引仅在运行时,在名为indexes的(非嵌套!)列表变量中已知。

示例:

如果indexes[4],我需要foo[4]

如果indexes[4,7],我需要foo[4][7]

如果indexes[4,7,3],我需要foo[4][7][3]

我能想到的是将命令字符串("foo[4][7][3]"放在最后一个示例中)放在一起,然后调用eval。 那将是eval("foo["+']['.join([str(n) for n in indexes])+']')

这很有效,并且足够短,但我希望有一种更简单,更pythonic的方式。

有没有人知道其他选择吗?

有没有办法分别处理空列表?如:

如果indexes[],我想要整个foo

if解决方案需要eval

编辑:我需要写入,而不是从元素中读取。我不认为现有的两个答案中的任何一个,也不是所指出的副本的答案都可以用于写作。抱歉误导。

2 个答案:

答案 0 :(得分:3)

You can use the reduce() function:

from functools import reduce  # Python 3 forward compatibility
import operator

def access(lst, indexes):
    return reduce(operator.getitem, indexes, lst)

You could use list.__getitem__ instead of operator.getitem, but then you limit the application to list objects only (it wouldn't work for tuples or dictionaries, the latter with keys rather than integer indices).

This repeatedly applies the indices, in order, to the previous result (starting the original list). This meets all your criteria, including the empty-list case:

>>> foo = ['a', 'b', 'c', 'd', ['foo', 'bar', 'baz', 'spam', 'eggs', 'ham', 'monty', ['alpha', 'beta', 'delta', 'gamma']]]
>>> access(foo, [])
['a', 'b', 'c', 'd', ['foo', 'bar', 'baz', 'spam', 'eggs', 'ham', 'monty', ['alpha', 'beta', 'delta', 'gamma']]]
>>> access(foo, [4])
['foo', 'bar', 'baz', 'spam', 'eggs', 'ham', 'monty', ['alpha', 'beta', 'delta', 'gamma']]
>>> access(foo, [4, 7])
['alpha', 'beta', 'delta', 'gamma']
>>> access(foo, [4, 7, 3])
'gamma'

If you needed to assign to the last element, keep the last index aside to then assign to that:

if indexes:
    target = access(foo, indexes[:-1])
    target[indexes[-1]] = new_value
else:
    foo = new_value

答案 1 :(得分:2)

You can set item to foo, then proceeds with the indexes list to access deeper nested elements:

def access (foo, indexes):
    item = foo
    for index in indexes:
        item = item[index]
    return item