Graphs and Kruskal's Algorithm - Python OOP
Type hints

def __init__(self, start, end, weight):


can be

def __init__(self, start: Vertex, end: Vertex, weight: float):


depending on a few things, including the order of declaration of your classes, Vertex might need to be 'Vertex' here.

For another example, this

def vertex_from_name(self, name):


can turn into

def vertex_from_name(self, name: str) -&gt; Vertex:


Efficient lookups

To make this more efficient:

    return next((v for v in self.vertices if v.name == name), None)


Consider maintaining a string-to-Vertex dictionary to reduce this lookup from O(n) to O(1) in time.

Premature materialization

These:

    return [e for e in self.edges if (e.start == v) or (e.end == v)]


    return [e.start for e in self.edges if e.end == v] + [e.end for e in self.edges if e.start == v]


require that the entire results be stored to an in-memory list. To return the generator directly and reduce this memory requirement, the first one can be

    return (e for e in self.edges if v in {e.start, e.end})


and the second one can be

yield from (e.start for e in self.edges if e.end == v)
yield from (e.end for e in self.edges if e.start == v)


Set-membership tests

This:

""" Given a list of lists, merges e1 root list with e2 root list and returns merged list."""


is probably better-expressed as accepting a list of set, not a list of lists. That will make these two tests:

        if e1 in i:
            xroot = i
        if e2 in i:
            yroot = i


faster. This:

    self.sets = [[v] for v in self.vertices]


would then become

    self.sets = [{v} for v in self.vertices]


Strings as iterables

This

v = [Vertex(x) for x in ["A", "B", "C", "D", "E", "F"]]


can be

v = [Vertex(x) for x in 'ABCDEF']


Convenience functions

Consider making a convenience function to turn this

g.add_edge("A", "B", 9)
g.add_edge("A", "C", 12)
g.add_edge("A", "D", 9)
g.add_edge("A", "E", 11)
g.add_edge("A", "F", 8)
g.add_edge("B", "C", 10)
g.add_edge("B", "F", 15)
g.add_edge("C", "D", 8)
g.add_edge("D", "E", 14)
g.add_edge("E", "F", 12)


into

g.add_edges(
    ("A", "B", 9),
    ("A", "C", 12),
    ("A", "D", 9),
    ("A", "E", 11),
    ("A", "F", 8),
    ("B", "C", 10),
    ("B", "F", 15),
    ("C", "D", 8),
    ("D", "E", 14),
    ("E", "F", 12),
)