【问题标题】:Convert flattened 1 dimensional indices to 2 dimensional indices将展平的一维索引转换为二维索引
【发布时间】:2019-10-02 07:59:23
【问题描述】:

假设我有一个列表列表,例如:

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

而且我有我希望定位的元素的“平面”索引,即如果它被展平为一维列表,我想从列表中选择的元素的索引:

flattened_indices = [0,1,4,9]

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

如何转换 1.d。索引到 2.d。允许我从原始嵌套列表中恢复元素的索引? IE。在这个例子中:

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

【问题讨论】:

  • 如果将列表展平并提取元素而不是将索引转换为 2D 会不会更容易?
  • 您可以通过查看列表的长度并进行一些简单的数学运算,将索引转换为二维索引。你试过了吗?
  • @AkshayNevrekar 实际问题比我使用的玩具模型要复杂一些,每个“子列表”实际上是子列表的可变长度子列表。因此,当第一个元素中可能有 3 个列表,但第二个元素中只有 2 个时,展平列表没有意义,而且您还可以为每个元素重用索引而不是展平多次。

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


【解决方案1】:

这是一种方法:

from bisect import bisect
import itertools

# Accumulated sum of list lengths
def len_cumsum(x):
    return 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]

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

【讨论】:

  • 我没有测试它,可能是某个地方的错误,不知道。这个想法是合理的。不过,您可以使用 list(itertools.accumulate(map(len, x))) 代替 len_cumsum 函数。
【解决方案2】:

我想你可以将这些索引对放在一个字典中,然后在末尾引用 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@jdehesa's 使用 bisect 的解决方案更加优化。

【讨论】:

  • 这假定x 包含按升序排列的自然数(即xx[i] == i,如果xx 是扁平列表)并且不适用于其他任何东西,例如x = [['a','a','a','a'],['a','a'],['a','a','a','a','a']]
猜你喜欢
  • 2022-01-05
  • 1970-01-01
  • 1970-01-01
  • 2019-05-22
  • 1970-01-01
  • 2023-01-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多