嵌套列表中重复列表的索引

4
我正在尝试解决与我的基因组对齐项目相关的问题,该问题如下所述: 如果给定一个嵌套列表 ``` y = [[1,2,3],[1,2,3],[3,4,5],[6,5,4],[4,2,5],[4,2,5],[1,2,8],[1,2,3]] ``` 将唯一列表的索引提取到嵌套列表中。 例如,上述嵌套列表的输出应为 ``` [[0,1,7],[2],[3],[4,5],[6]]。 ``` 这是因为列表 `[1,2,3]` 存在于索引位置 `0,1,7`,列表 `[3,4,5]` 存在于索引位置 `2`,以此类推。
由于我将处理大型列表,请问在Python中实现这个目标的最佳方式是什么?

1
你尝试过什么?问题具体是什么? - AMC
4个回答

7
你可以创建一个字典(如果在较旧版本的Python上,则使用OrderedDict)。字典的键将是子列表的元组,值将是索引数组。循环后,字典的值将保存你的答案:
from collections import OrderedDict

y = [[1,2,3],[1,2,3],[3,4,5],[6,5,4],[4,2,5],[4,2,5],[1,2,8],[1,2,3]]

lookup = OrderedDict()
for idx,l in enumerate(y):
    lookup.setdefault(tuple(l), []).append(idx)

list(lookup.values())
# [[0, 1, 7], [2], [3], [4, 5], [6]]

"older pythons" 的意思是:在 Python 3.6 中,有序性方面已经可以工作,在 Python 3.7 或更高版本中则得到了保证。详见此帖子 - colidyre
1
这个解决方案比我的更快,更优雅,运行速度更快。+1 - PacketLoss
1
这种方法即使对于大型列表也非常高效。谢谢! - sindhuja

3
你可以使用列表推导式和range函数来检查重复的索引并将它们添加到result中。
result = []
for num in range(len(y)):
    occurances = [i for i, x in enumerate(y) if x == y[num]]
    if occurances not in result: result.append(occurances)

result
#[[0, 1, 7], [2], [3], [4, 5], [6]]

2
考虑使用numpy解决这个问题:
import numpy as np

y = [
    [1, 2, 3],
    [1, 2, 3],
    [3, 4, 5],
    [6, 5, 4],
    [4, 2, 5],
    [4, 2, 5],
    [1, 2, 8],
    [1, 2, 3]
]

# Returns unique values of array, indices of that
# array, and the indices that would rebuild the original array
unique, indices, inverse = np.unique(y, axis=0, return_index=True, return_inverse=True)

这是每个变量的打印输出:
unique = [
[1 2 3]
[1 2 8]
[3 4 5]
[4 2 5]
[6 5 4]]

indices = [0 6 2 4 3]

inverse = [0 0 2 4 3 3 1 0]

如果我们看一下变量inverse,我们可以看到我们确实得到了[0, 1, 7]作为第一个唯一元素[1,2,3]的索引位置,现在我们需要适当地将它们分组。
new_list = []
for i in np.argsort(indices):
    new_list.append(np.where(inverse == i)[0].tolist()) 

输出:

new_list = [[0, 1, 7], [2], [3], [4, 5], [6]]

最后,上面代码的参考文献:
Numpy - unique(唯一值)、where(条件筛选)、argsort(排序索引)

2

另外一个解决方案:

y = [[1, 2, 3], [1, 2, 3], [3, 4, 5], [6, 5, 4], [4, 2, 5], [4, 2, 5], [1, 2, 8], [1, 2, 3]]

occurrences = {}

for i, v in enumerate(y):
    v = tuple(v)
    if v not in occurrences:
        occurrences.update({v: []})
    occurrences[v].append(i)

print(occurrences.values())

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接