反转索引列表列表

Nic*_*mer 1 python list

我有一份指数清单,例如,

a = [
    [2],
    [0, 1, 3, 2],
    [1],
    [0, 3]
    ]
Run Code Online (Sandbox Code Playgroud)

我现在想"反转"这个名单:数字0出现在索引13,所以:

b = [
    [1, 3],
    [1, 2],
    [0, 1],
    [1, 3]
    ]
Run Code Online (Sandbox Code Playgroud)

关于如何快速做到这一点的任何提示?(我正在处理的列表可能很大.)

额外奖励:我知道每个索引都会出现两次a(就像上面的例子一样).

Mar*_*ers 5

使用字典收集反向索引,用于enumerate()生成a条目的索引:

inverted = {}
for index, numbers in enumerate(a):
    for number in numbers:
        inverted.setdefault(number, []).append(index)

b = [inverted.get(i, []) for i in range(max(inverted) + 1)]
Run Code Online (Sandbox Code Playgroud)

字典为您提供了有效的随机访问以添加反转,但这确实意味着您需要考虑反转中可能缺少的索引,因此range(max(inverted))循环以确保涵盖0和最大值之间的所有索引.

演示:

>>> a = [
...     [2],
...     [0, 1, 3, 2],
...     [1],
...     [0, 3]
...     ]
>>> inverted = {}
>>> for index, numbers in enumerate(a):
...     for number in numbers:
...         inverted.setdefault(number, []).append(index)
...
>>> [inverted.get(i, []) for i in range(max(inverted) + 1)]
[[1, 3], [1, 2], [0, 1], [1, 3]]
Run Code Online (Sandbox Code Playgroud)


use*_*559 5

此代码依赖于每个数字恰好出现两次的事实.它也非常简单,避免了构建字典然后从那里复制结果的开销:

a = [
        [2],
        [0, 1, 3, 2],
        [1],
        [0, 3]
    ]

b = []

for i, nums in enumerate(a):

    # For each number found at this index
    for num in nums:


        # If needed, extend b to cover the new needed range
        b += [[] for _ in range(num + 1 - len(b)]

        # Store the index
        b[num].append(i)

print(b)

# Output:
# [[1, 3], [1, 2], [0, 1], [1, 3]]
Run Code Online (Sandbox Code Playgroud)