简体   繁体   English

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

[英]make new python lists with indexes from items in a single list

I want to take a list, eg [0, 1, 0, 1, 2, 2, 3] , and make a list of lists of (index + 1) for each of the unique elements. 我想获取一个列表,例如[0, 1, 0, 1, 2, 2, 3] ,并为每个唯一元素制作一个列表(index + 1) For the above, for example, it would be [[1, 3], [2, 4], [5, 6], [7]] . 对于上述情况,例如,将为[[1, 3], [2, 4], [5, 6], [7]]

Right now my solution is the ultimate in clunkiness: 现在,我的解决方案是笨拙的终极解决方案:

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

Any thoughts on a more pythonic way to do this would be much appreciated! 任何以更pythonic的方式进行此操作的想法将不胜感激!

I would do this in two steps: 我将分两步执行此操作:

  1. Build a map {value: [list, of, indices], ...} : 建立地图{value: [list, of, indices], ...}

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

     master = [index_map.get(index, []) for index in range(max(index_map)+1)] 

For your example, this would give: 以您的示例为例:

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

This implementation iterates over the whole list only once ( O(n) , where n is len(list_1) ) whereas the others so far iterate over the whole list once for each unique element ( O(n*m) , where m is len(set(list_1)) ). 此实现仅对整个列表进行一次迭代( O(n) ,其中nlen(list_1) ),而到目前为止,其他实现针对每个唯一元素对整个列表进行一次迭代( O(n*m) ,其中mlen(set(list_1)) )。 By taking max(d) rather than max(list_1) you only need to iterate over the length of the unique items, which is also more efficient. 通过使用max(d)而不是max(list_1)您只需要遍历唯一项的长度,这也更加有效。

The implementation can be slightly simpler if you make d = collections.defaultdict(list) . 如果使d = collections.defaultdict(list)则实现可能会稍微简单一些。

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

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

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])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM