使用变量元组访问列表的元素



免责声明:初学者,自学Python用户。

ndarrays的一个非常酷的特性是它们能够接受整数元组作为索引(例如myNDArray[(1,2)] == myNDArray[1][2])。这允许我将索引保留为未指定的变量(例如indices tuple),直到脚本确定要使用ndarray的哪个部分,在这种情况下,变量被指定为整数元组,并用于访问ndarray(例如myNDArray[indicesTuple])的一部分。使用变量的实用性在于,元组的LENGTH可以根据ndarray的维度而变化。

然而,这限制了我使用数值数组。我尝试过使用列表,但它们不能将元组作为索引(例如,myList[(1,2)]给出了一个错误。)。有没有一种方法可以像对函数参数那样"打开"列表索引的元组?或者更简单或更高效的东西?

更新:天哪,我忘了它的存在。基本上,我最终了解到可以使用参数dtype=object初始化ndarray,这允许ndarray包含多种类型的Python对象,就像列表一样。至于访问列表,正如一位评论者所指出的,我可以使用for循环来迭代变量indices Tuple,以访问列表中越来越多的嵌套元素。对于现场编辑,请参阅已接受的评论,在那里真的付出了额外的努力。

我将您的问题解释为:

我有一个N维列表和一个包含N个值(T1,T2…TN)的元组。如何使用元组值访问列表?我不知道N会是什么。

我不知道有什么内置的方法可以做到这一点,但您可以编写一个方法,反复挖掘列表,直到达到最里面的值。

def get(seq, indices):
    for index in indices:
        seq = seq[index]
    return seq
seq = [
    [
        ["a","b"],
        ["c","d"]
    ],
    [
        ["e","f"],
        ["g","h"]
    ]
]
indices = [0,1,0]
print get(seq, indices)

结果:

c

您也可以使用reduce在一行中完成这项工作,尽管读者不太清楚您想要实现什么。

print reduce(lambda s, idx: s[idx], indices, seq)

(*如果使用3.X,则需要从functools导入reduce。因此,需要两行。)


如果要在N维列表中设置值,请使用get访问列表的第二深级别,并将其分配给该级别。

def set(seq, indices, value):
    innermost_list = get(seq, indices[:-1])
    innermost_list[indices[-1]] = value

假设您有一个(i,j)索引列表

indexList = [(1,1), (0,1), (1,2)]

还有一些你想从索引的2D列表

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

你可以使用如下的列表理解来获得这些元素

>>> [l[i][j] for i,j in indexList]
[5, 2, 6]

然后你的索引可以是你想要的任何索引。它们将在列表理解中被解压缩,并用作列表索引。对于您的特定应用程序,我们必须了解索引变量的来源,但这只是一般的想法。

Python没有多维列表,因此myList[(1,2)]只能被认为是(myList[1], myList[2])的快捷方式(尽管可以使用import operator; x = operator.itemgetter(1,2)(myList)来实现这一点,但有时这会非常方便)。

如果你的myList看起来像

myList = [ ["foo", "bar", "baz"], ["a", "b", c" ] ]

那么CCD_ 13将不起作用(或有意义),因为CCD_。使用myList[1][2]是因为第一个索引myList[1]返回对["a", "b", "c"]的引用,对其应用第二个索引[2]以获得"c"

稍微相关一点,可以使用字典通过使用元组作为默认字典的键来精确地模拟稀疏数组。

import collections
d = collections.defaultdict(str)
d[(1,2)] = "foo"
d[(4,5)] = "bar"

尝试用作键的任何其他元组都将返回空字符串。这不是一个完美的模拟,因为如果不使用之类的东西,就无法访问阵列的整行或整列

row1 = [d[1, x] for x in range(C)] # where C is the number of columns
col3 = [d[x, 3] for x in range(R)] # where R is the number of columns

使用按元组索引的字典

>>> width, height = 7, 6
>>> grid = dict(
        ((x,y),"x={} y={}".format(x,y))
        for x in range(width)
        for y in range(height))
>>> print grid[3,1]
x=3 y=1

使用列表列表

>>> width, height = 7, 6
>>> grid = [
        ["x={} y={}".format(x,y) for x in range(width)]
        for y in range(width)]
>>> print grid[1][3]
x=3 y=1

在这种情况下,您可以制作一个getter和setter函数:

def get_grid(grid, index):
    x, y = index
    return grid[y][x]
def set_grid(grid, index, value):
    x, y = index
    grid[y][x] = value

您可以更进一步,创建自己的类,该类包含列表列表,并定义一个将元组作为索引的索引器,并执行相同的过程。它可以进行比字典更明智的边界检查,并提供更好的诊断,但它需要一些设置。我认为字典法适合快速探索。

最新更新