说我有一个列表列表,例如:
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)]
答案 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解决方案更为理想。