Considering that the nested list looks like the following
L = [['John','Sayyed'],['John','Simon'],['bush','trump'],['Sam','Suri','NewYork'],['Suri','Orlando','Canada']]
Below I will share two potential options to solve OP's problem.
Option 1
Using (the comments make it self-explanatory):
L = [set(l) for l in L] # Convert the list of lists to a list of sets
for i in range(len(L)): # For each set
for j in range(i+1,len(L)): # For each set after the current set
if len(L[i].intersection(L[j])) > 0: # If the two sets have a common element
L[i] = L[i].union(L[j]) # Union the two sets
L[j] = set() # Empty the second set
L = [list(l) for l in L if len(l) > 0] # Remove empty sets and convert the list of sets to a list of lists
Which will give us
[['John', 'Sayyed', 'Simon'], ['bush', 'trump'], ['NewYork', 'Sam', 'Canada', 'Suri', 'Orlando']]
For the sake of convenience, one might want to refactor it
def union(L):
L = [set(l) for l in L] # Convert the list of lists to a list of sets
for i in range(len(L)): # For each set
for j in range(i+1,len(L)): # For each set after the current set
if len(L[i].intersection(L[j])) > 0: # If the two sets have a common element
L[i] = L[i].union(L[j]) # Union the two sets
L[j] = set() # Empty the second set
L = [list(l) for l in L if len(l) > 0] # Remove empty sets and convert the list of sets to a list of lists
return L
And then simply
L_new = union(L)
[Out]: [['John', 'Sayyed', 'Simon'], ['bush', 'trump'], ['NewYork', 'Sam', 'Canada', 'Suri', 'Orlando']]
Option 2
Using NetworkX
.
One starts by creating an empty graph with no nodes and no edges.
G = nx.Graph()
Then, in order to add the nodes, there are various options, such as using Graph.add_nodes_from
and Graph.add_edge
for l in L: # For each sublist
G.add_nodes_from(l) # Add all the elements of the sublist as nodes
for i in range(len(l)): # For each element in the sublist
for j in range(i+1,len(l)): # For each element after the current element
G.add_edge(l[i],l[j]) # Add an edge between the two elements
# or
for l in L: # For each sublist
G.add_nodes_from(l) # Add all nodes in the sublist to the graph
for i in range(len(l)-1): # For each node in the sublist
G.add_edge(l[i],l[i+1]) # Add an edge between the current node and the next node in the sublist
Then, finally, one can get a list of the connected components with connected_components
L = list(nx.connected_components(G))
[Out]: [{'John', 'Sayyed', 'Simon'}, {'bush', 'trump'}, {'NewYork', 'Sam', 'Canada', 'Suri', 'Orlando'}]
As an additional step, one might want to plot the graphs. For that, NetworkX
provides basic functionality for visualizing graphs. See here more information on drawing graphs with NetworkX
.
One approach would be with matplotlib
.
There are various layouts one can use, such as:
spring_layout
import matplotlib.pyplot as plt
# Create the layout for the graph
pos = nx.spring_layout(G, k=0.5, iterations=20, scale=10)
# Draw the graph with the layout
nx.draw(G, pos, with_labels=True, font_weight='bold', font_color='white', node_size=2500, node_color='blue')
# Show the plot
plt.show()

spring_layout
import matplotlib.pyplot as plt
# Create the layout for the graph
pos = nx.spiral_layout(G, scale=5)
# Draw the graph with the layout
nx.draw(G, pos, with_labels=True, font_weight='bold', font_color='white', node_size=2500, node_color='blue')
# Show the plot
plt.show()

shell_layout
import matplotlib.pyplot as plt
# Create the layout for the graph
pos = nx.shell_layout(G, scale=10)
# Draw the graph with the layout
nx.draw(G, pos, with_labels=True, font_weight='bold', font_color='white', node_size=2500, node_color='blue')
# Show the plot
plt.show()

and more, depending on one's use case and goal. See here all the available layouts.