将元组转换为索引?

时间:2015-07-06 16:26:23

标签: python python-2.7

初看起来似乎微不足道,但令人惊讶的是我没有在网上找到任何答案 - 请考虑以下列表:

my_list = [[1,2,3], [4,5,6], [7,8,9]]

为了获得5分,我当然可以在my_list[1][1]以5分的位置前进。

假设我有以下元组:

t = (1, 1)

我是否可以使用此元组以便以my_list[t[0]][t[1]]更吸引人的方式获得5?

修改:请同时考虑作业,即更具吸引力

my_list[t[0]][t[1]] = value

以及不一定是数字的最终元素,例如[['a', 'b'], ['c', 'd']]

5 个答案:

答案 0 :(得分:3)

使用reduce

result = reduce(lambda acc, i: acc[i], t, my_list)

演示:

>>> my_list = [[1,2,3], [4,5,6], [7,8,9]]
>>> t = (1, 1)
>>> reduce(lambda acc, i: acc[i], t, my_list)
5

更新

如果需要更新:

reduce(lambda acc, i: acc[i], t[:-1], my_list)[t[-1]]

返回“左值”(如果我可以这样说)。但它变得丑陋,因为表达的一致性被打破了。实际上,它也不能作为一种功能包装。

我建议写一个这样的简单包装:

class mdlist(list):
    def __getitem__(self, item):
        if isinstance(item, tuple):
            assert len(item) >= 1
            return self[item[0]][item[1:]] if len(item) > 1 else self[item[0]]
        else:
            return super(mdlist, self).__getitem__(item)

    def __setitem__(self, item, value):
        if isinstance(item, tuple):
            assert len(item) >= 1
            if len(item) > 1:
                self[item[0]][item[1:]] = value
            else:
                self[item[0]] = value
        else:
            super(mdlist, self).__setitem__(item, value)

它不会比你想象的更多,也会让你的生活变得更轻松。

答案 1 :(得分:2)

我认为NumPy包适合您的需要。首先将列表转换为NumPy数组,然后您可以通过其位置元组选择项目。

import numpy as np

my_list = [[1,2,3], [4,5,6], [7,8,9]]
my_array = np.array(my_list)
t = (1, 1)
print my_array[t]

答案 2 :(得分:1)

您可以使用元组解包来获取元组值(最终将索引列入变量)

>>> one , two = t
>>> mylist[one][two]
5

答案 3 :(得分:1)

您可以编写一个函数来执行此操作:

def nested_index(l, t):
    e = l
    for i in t:
        e = e[i]
    return e

然后你可以把这个函数称为:

nested_index(my_list, t)

答案 4 :(得分:0)

您可以创建operator.itemgetter个对象并连续应用它们。

两个嵌套级别的示例:

import operator
a = [[1,2,3], [4,5,6], [7,8,9]]
t = (1,2)
i1, i2 = map(operator.itemgetter, t)

>>> i2(i1(a))
6

n级嵌套的示例(您必须确保目标结构可以容纳元组的长度,可以将其包装在try / except中):

a = [[[1,2,3], [4,5,6]], [[7,8,9],['a','b','c']]]
t = (0,1,0) # should produce 4
z = a[:]
for op_ig in map(operator.itemgetter, t):
    z = op_ig(z)

>>> z
4

使用functionally

中的几个函数更进一步
from functionally import compose, thrush
a = [[[1,2,3], [4,5,6]], [[7,8,9],['a','b','c']]]
t = (1,1,0) # should produce a
foo = compose(*map(operator.itemgetter, reversed(t)))

>>> foo(a)
'a'
>>> thrush(a, *(operator.itemgetter(i) for i in t))
'a'