使用单个列表中的项目的索引创建新的python列表

时间:2015-08-19 14:28:53

标签: python list

我想要一个列表,例如[0, 1, 0, 1, 2, 2, 3],并为每个唯一元素列出(index + 1)列表。例如,对于上述内容,它将是[[1, 3], [2, 4], [5, 6], [7]]

现在我的解决方案是最终的笨拙:

list_1 = [0, 1, 0, 1, 2, 2, 3]
maximum = max(list_1)
master = []
for i in range(maximum + 1):
    temp_list = []
    for j,k in enumerate(list_1):
        if k == i:
            temp_list.append(j + 1)
    master.append(temp_list)
print master

任何关于以更加pythonic的方式做这件事的想法都会非常感激!

3 个答案:

答案 0 :(得分:3)

我会分两步完成:

  1. 制作地图{value: [list, of, indices], ...}

    index_map = {}
    for index, value in enumerate(list_1):
        index_map.setdefault(value, []).append(index+1)
    
  2. 将字典中的值列表提取到master列表中:

    master = [index_map.get(index, []) for index in range(max(index_map)+1)]
    
  3. 对于您的示例,这将给出:

    >>> index_map
    {0: [1, 3], 1: [2, 4], 2: [5, 6], 3: [7]}
    >>> master
    [[1, 3], [2, 4], [5, 6], [7]]
    

    此实现仅在整个列表上迭代一次(O(n),其中nlen(list_1))而其他人到目前为止迭代整个列表一次为每个唯一元素O(n*m),其中mlen(set(list_1)))。通过取max(d)而不是max(list_1),您只需迭代唯一项的长度,这也更有效。

    如果您制作d = collections.defaultdict(list),则实施可能会稍微简单一些。

答案 1 :(得分:0)

master = [[i+1 for i in range(len(list_1)) if list_1[i]==j] for j in range(max(list_1)+1)]

它与您当前的代码相同,但它使用列表理解,这通常是解决此类问题的非常好的pythonic方法。

答案 2 :(得分:0)

list_1 = [0, 1, 0, 1, 2, 2, 3]
master = []
for i in range(max(list_1)+1):
    master.append([j+1 for j,k in enumerate(list_1) if k==i])