I am trying to make a list of groups that I extract from a list of lists. The main list I have contains lists which are of different lengths. I want to group up all the sub-lists that contain at least one value from another sub-list efficiently. For instance I want this:
[[2],[5],[5,8,16],[7,9,12],[9,20]]
to be grouped up like this
my_groups = {"group1":[2], "group2":[5,8,16], "group3":[7,9,12,20]}
The way I thought of doing this is to create convert the sub-lists into sets and using reduce intersect1d
reduce(np.intersect1d, (SUPERLIST))
and then put the results in a dictionary. But I don't know how to convert it to an array of sets without iterating through the list. Is there a way to do this or a more efficient way that I am missing?
Edit
Without numpy I would do something like this:
my_dict = dict()
unique_id = 0
for sub_list_ref in super_list:
sub_set_ref = set(sub_list_ref)
for sub_list_comp in super_list:
sub_set_comp = set(sub_list_comp)
if len(sub_set_ref.intersection(sub_set_comp))>0:
my_dict[unique_id] = sub_set_ref.union(sub_set_comp)
updated_id = unique_id+1
if updated_id == unique_id:
my_dict[unique_id] = sub_list_ref
else:
unique_id = updated_id
Edit 2
Yesterday this question got an excellent answer from DarryIG and today I managed to make a more efficient version.
def coalesce_groups(current_list, super_list, iterations):
if iterations <= 0:
print("YOU HAVE ITERATED MORE THAN 3 TIMES")
tmp_list = current_list
for element in current_list:
tmp_list = tmp_list + super_list[element]
# Take only the unique elements
tmp_list = list(set(tmp_list))
if tmp_list == list(set(current_list)):
return tmp_list
else:
iterations-=1
return coalesce_groups(tmp_list, super_list, iterations)
def dict_of_groups(original_list):
lst = list(original_list).copy()
result_list = []
for it in lst:
result = coalesce_groups(it, lst, iterations = 3)
if len(result)!=0:
result_list.append(result)
for t in result:
lst[t] = []
result_dict = { x : result_list[x] for x in range(0, len(result_list) ) }
return result_dict
In test (on jupyter notebook)
lst = [[0], [1], [2], [3], [4], [5], [16, 6], [8, 10, 18, 21, 27, 7], [10, 19, 21, 27, 40, 8], [13, 20, 22, 26, 28, 30, 34, 41, 42, 50, 9], [18, 21, 27, 10], [11], [12], [20, 22, 26, 28, 30, 34, 41, 42, 50, 13], [14], [15], [16], [25, 17], [21, 27, 40, 18], [21, 27, 40, 19], [22, 26, 28, 30, 34, 41, 42, 50, 20], [27, 40, 21], [26, 28, 30, 34, 41, 42, 50, 22], [23], [24], [25], [28, 30, 34, 41, 42, 50, 26], [40, 27], [30, 34, 41, 42, 50, 28], [29], [34, 41, 42, 50, 30], [33, 31], [32], [33], [41, 42, 50, 34], [35], [36], [37], [38], [39], [40], [42, 50, 41], [50, 42], [43], [44], [45], [46], [47], [49, 48], [49], [50]]
%lprun -T lprof0 -f generate_groups generate_groups(lst)
print(open('lprof0', 'r').read())
%lprun -T lprof1 -f dict_of_groups dict_of_groups(lst)
print(open('lprof1', 'r').read())
Additional answers will be taken into consideration but I believe his is still valid and the more complete for this question.
DarryIG is still king
setobjects insidenumpy.ndarrayobjects? That makes very little sense.