从Python中的列表中的列表构造函数

时间:2011-12-21 08:52:20

标签: python list function

我很难理解如何构建一个从内到外在列表中的列表上工作的函数(我想你可能很难描述它)。

我正在尝试动态转换像

这样的列表
res = SomeDjangoQuerySet
x = ['neighborhood', ['city', ['metro', 'metro']]]

成:

getattr(getattr(getattr(getattr(res, 'neighborhood'), 'city'), 'metro'), 'metro')

AKA:

getattr(getattr(getattr(getattr(res, x[0]), x[1][0]), x[1][1][0]), x[1][1][1])

基本上,第一个值将始终是一个字符串,第二个值将是字符串或列表。每个列表都将遵循此模式(字符串,字符串或列表)。列表中列表的深度是不确定的。 getattr()的最里面的第一个值将是一个外部变量(在这种情况下为“res”)。有什么建议吗?

3 个答案:

答案 0 :(得分:3)

这听起来像递归和迭代可能是有用的。这样做你想要的吗?

def flatten(data):
    res = []
    if hasattr(data, '__iter__'):
        for el in data:
            res.extend(flatten(el))
    else:
        res.append(data)
    return res


reduce(getattr, flatten(x), res)

答案 1 :(得分:1)

def nestattr(x, y):
    if isinstance(y, str):
        return getattr(x, y)
    elif isinstance(y, list):
        return nestattr(getattr(x, y[0]), y[1])

nestattr(res, x)

所以你从列表中的第一个字符串开始,你有(1)查询的getattr和(2)该字符串。然后你使用该列表的其余部分递归,如果它是一个字符串,你只需要{1}}(1)上一个getattr的结果和(2)这个字符串。否则,如果它仍然是列表,则重复。我想这就是你要找的东西?如果我错了,请纠正我。

答案 2 :(得分:1)

我最后花了一些时间学习递归,发现这是最简单的解决方案(尽管,David Zwicker也提供了一个可行的解决方案)。

def recursion(a, b):
    if type(b) is list:
        return recursion(getattr(a, b[0]), b[1])
    else:
        return getattr(a, b)

recursion(res, x)