将一维索引转换为二维索引

时间:2019-05-15 08:33:55

标签: python python-3.x nested-lists indices

说我有一个列表列表,例如:

x = [[0,1,2,3],[4,5],[6,7,8,9,10]]

并且我希望定位的元素具有“扁平”索引:

indices = [0,1,4,9]

即,如果要展平到一维列表中,则要从列表中选择元素的索引:

                  # #     #         #
flattened_list = [0,1,2,3,4,5,6,7,8,9,10]

如何转换1.d。索引到2.d。索引,使我能够从原始嵌套列表中恢复元素?即在此示例中:

2d_indices = [(0,0), (0,1), (1,0), (2,3)]

2 个答案:

答案 0 :(得分:3)

这是一种实现方法:

from bisect import bisect

# Accumulated sum of list lengths
def len_cumsum(x):
    c = [len(lst) for lst in x]
    for i in range(1, len(c)):
        c[i] += c[i - 1]
    return c
# As pointed out by @tobias_k, this can actually be just done as:
# list(itertools.accumulate(map(len, x)))

# Find 2D index from accumulated list of lengths
def find_2d_idx(c, idx):
    i1 = bisect(c, idx)
    i2 = (idx - c[i1 - 1]) if i1 > 0 else idx
    return (i1, i2)

# Test
x = [[0, 1, 2, 3], [4, 5], [6, 7, 8, 9, 10]]
indices = [0, 4, 9]
flattened_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
c = len_cumsum(x)
idx_2d = [find_2d_idx(c, i) for i in indices]
print(idx_2d)
# [(0, 0), (1, 0), (2, 3)]
print([x[i1][i2] for i1, i2 in idx_2d])
# [0, 4, 9]

如果您有很多“平面”索引,则比迭代每个索引的嵌套列表更有效。

答案 1 :(得分:0)

我想您可以将这些索引对放入字典中,然后仅引用末尾indices的字典并创建一个新列表:

x = [[0,1,2,3],[4,5],[6,7,8,9,10]]

indices = [0,4,9]

idx_map = {x: (i, j) for i, l in enumerate(x) for j, x in enumerate(l)}

result = [idx_map[x] for x in indices]
print(result)

这将导致:

[(0, 0), (1, 0), (2, 3)]

但这并不是最佳选择,因为它是二次创建idx_map的运行时。使用bisect的@jdehesa's解决方案更为理想。