【问题标题】:Access nested list element, depth known in runtime访问嵌套列表元素,深度在运行时已知
【发布时间】:2016-11-28 19:46:18
【问题描述】:

我想写入名为 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

这需要eval 解决方案中的if

编辑:我需要写入,而不是读取元素。我认为这两个现有答案中的任何一个,以及指定副本的答案,都不能用于写作。为误导而道歉。

【问题讨论】:

  • 不要使用eval,使用ast.literal_eval
  • result = foo; for index in indexes: result = result[index]; return result?没有evaluating,字面意思或其他方式,并按照你想要的方式对待空的indexes
  • @jonrsharpe 更好!我写了一个递归方法,但是不值得。
  • @TigerhawkT3:我知道我之前回答过这个问题,但在我的回答列表中找不到!
  • @MartijnPieters - 我可以发誓我在某个地方也有一个,像 Jon 描述的那样有一个简单的循环,但我似乎找不到它。

标签: python python-2.7 list


【解决方案1】:

您可以使用reduce() function:

from functools import reduce  # Python 3 forward compatibility
import operator

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

可以使用list.__getitem__ 而不是operator.getitem,但随后您将应用程序限制为仅列出对象(它不适用于元组或字典,后者使用键而不是整数索引)。

这会按顺序重复将索引应用于先前的结果(从原始列表开始)。这符合您的所有标准,包括空列表案例:

>>> 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'

如果您需要 分配 到最后一个元素,请将 last 索引放在一边,然后再分配给它:

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

【讨论】:

    【解决方案2】:

    您可以将item 设置为foo,然后继续使用索引列表来访问更深的嵌套元素:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多