简体   繁体   English

如何在Python的列表列表中对元素进行分组?

[英]How to group elements in a list of lists in Python?

I'm trying to efficientlly group / nest a list of vertices by their neighbourhood size, into a list of lists of vertices. 我正在尝试根据邻域的大小有效地将顶点列表分组/嵌套到顶点列表中。

The neighbourhood size is a property of a vertex v can be obtained by calling len(v.neighbours) . 邻域大小是顶点v的属性,可以通过调用len(v.neighbours)

The input I have is an unsorted list of vertices. 我输入的内容是未排序的顶点列表。 The output I'm trying to obtain should look like this: 我尝试获取的输出应如下所示:

[[all vertices with len(v.neighbours) == 1], [... == 2], [... == 4]]    

It should be a list of lists where each sublist contains vertices with the same neighbourhood size, sorted from small to big, without empty lists. 它应该是一个列表列表,其中每个子列表包含具有相同邻域大小的顶点,从小到大排序,没有空列表。 I don't need the indices of the sublists to map to the neighbourhood size of the contained vertices. 我不需要子列表的索引来映射到所包含顶点的邻域大小。

I know how to achieve this with list comprehension, but it's rather inefficient: 我知道如何通过列表理解来实现这一点,但是效率很低:

def _group(V: List[Vertex], max: int) -> List[List[Vertex]]:
    return [[v for v in V if v.label == i] for i in range(max)]

Additionally, I don't want to pass the maximum neighbourhood size as a parameter, but calculate that during the grouping, and I'm looking for a way to filter out empty lists during the grouping as well. 另外,我不想将最大邻域大小作为参数传递,而是在分组期间进行计算,并且我也在寻找一种在分组期间过滤出空列表的方法。

I've looked into more efficient ways to group the vertices, for example by using a dictionary as intermediary step, but I haven't managed to produce a working result. 我已经研究了将顶点分组的更有效方法,例如,通过使用字典作为中介步骤,但是我没有设法产生工作结果。

Could anyone tell me the most efficient way to group / nest the list of vertices? 谁能告诉我对顶点列表进行分组/嵌套的最有效方法?

Thanks in advance, and sorry if this has been posted before, but I couldn't find what I was looking for in another question. 在此先感谢您,如果在此之前已经发布过,则对不起,但是在另一个问题中我找不到我想要的东西。

One pass over the input, put the result in an intermediate dictionary, work the dictionary into the output you want. 将输入传递一遍,将结果放入中间字典中,然后将字典工作到所需的输出中。

temp_result = defaultdict(list)

for v in vertices:
    temp_result[neighborhood_size(v)].append(v)

max_size = max(temp_result.keys())

return_val = list()
for i in range(max_size):
    if temp_result[i]: # check if empty
        return_val.append(temp_result[i])

You can build it this way: 您可以通过以下方式构建它:

from collections import defaultdict

# Create a dict {nb_of_neighbours:[corresponding vertices]}
vertices_by_neighbours = defaultdict(list)
for v in vertices:
    vertices_by_neighbours[len(v.neighbours)].append(v)

# Create the output list, sorted by number of neighbours    
out = []
for nb_neighbours in sorted(vertices_by_neighbours):
    out.append(vertices_by_neighbours[nb_neighbours])

# Max number of neighbours, in case you want it...
max_neighbours = max(vertices_by_neighbours)

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

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