使用Python在元组数组中查找循环长度

使用Python在元组数组中查找循环长度,python,tuples,cycle,Python,Tuples,Cycle,我有一个元组数组;说 [(1,2), (2,1), (3,4), (4,5), (5,3)] 在上述过程中有两个循环;长度2和长度3中的一个。Python中是否有内置函数或包允许我返回所有周期长度的列表?对于上面的示例,它应该返回[2,3]。您可以使用第三方库: 您可以使用第三方库: 演示的NetworkX也是我的选择。但这是一个第三方项目,由于您明确要求: 是否有内置函数或包 实际上有一个stdlib可以提供帮助:在python3.9中是新的 里面还没有多少。它没有从图中提取循环长度的函数,

我有一个元组数组;说

[(1,2), (2,1), (3,4), (4,5), (5,3)]

在上述过程中有两个循环;长度2和长度3中的一个。Python中是否有内置函数或包允许我返回所有周期长度的列表?对于上面的示例,它应该返回[2,3]。

您可以使用第三方库:


您可以使用第三方库:

演示的NetworkX也是我的选择。但这是一个第三方项目,由于您明确要求:

是否有内置函数或包

实际上有一个stdlib可以提供帮助:在python3.9中是新的

里面还没有多少。它没有从图中提取循环长度的函数,但有一个拓扑排序器类可以生成非循环图中节点的拓扑排序。拓扑分拣机在输入中检测到循环时引发异常:

class CycleError(ValueError):
    """Subclass of ValueError raised by TopologicalSorter.prepare if cycles
    exist in the working graph.

    If multiple cycles exist, only one undefined choice among them will be reported
    and included in the exception. The detected cycle can be accessed via the second
    element in the *args* attribute of the exception instance and consists in a list
    of nodes, such that each node is, in the graph, an immediate predecessor of the
    next node in the list. In the reported list, the first and the last node will be
    the same, to make it clear that it is cyclic.
    """
特别值得注意的是,错误实际上揭示了循环,因此无需太多额外工作,您就可以通过拓扑分类器从图形中提取循环长度。创建图形分类器:

import graphlib

edges = [(1,2), (2,1), (3,4), (4,5), (5,3)]
ts = graphlib.TopologicalSorter()
for edge in edges:
    ts.add(*edge)
然后编写一个helper函数,从失败的调用中提取一个循环:

例如:

>>> cycle = get_cycle(ts)
>>> print(cycle)
[(2, 1), (1, 2)]
>>> print(len(cycle))
2
请注意,这仅返回遇到的第一个循环。若要查找另一个循环,请从图形中删除检测到的循环的边,打破该循环并重复此过程,直到找到所有循环

>>> edges.remove(cycle[0])
>>> ts = ...
>>> get_cycle(ts)
[(5, 3), (4, 5), (3, 4)]
NetworkX可能更简单,所以如果可以的话就使用它吧

演示的NetworkX,这也是我的选择。但这是一个第三方项目,由于您明确要求:

是否有内置函数或包

实际上有一个stdlib可以提供帮助:在python3.9中是新的

里面还没有多少。它没有从图中提取循环长度的函数,但有一个拓扑排序器类可以生成非循环图中节点的拓扑排序。拓扑分拣机在输入中检测到循环时引发异常:

class CycleError(ValueError):
    """Subclass of ValueError raised by TopologicalSorter.prepare if cycles
    exist in the working graph.

    If multiple cycles exist, only one undefined choice among them will be reported
    and included in the exception. The detected cycle can be accessed via the second
    element in the *args* attribute of the exception instance and consists in a list
    of nodes, such that each node is, in the graph, an immediate predecessor of the
    next node in the list. In the reported list, the first and the last node will be
    the same, to make it clear that it is cyclic.
    """
特别值得注意的是,错误实际上揭示了循环,因此无需太多额外工作,您就可以通过拓扑分类器从图形中提取循环长度。创建图形分类器:

import graphlib

edges = [(1,2), (2,1), (3,4), (4,5), (5,3)]
ts = graphlib.TopologicalSorter()
for edge in edges:
    ts.add(*edge)
然后编写一个helper函数,从失败的调用中提取一个循环:

例如:

>>> cycle = get_cycle(ts)
>>> print(cycle)
[(2, 1), (1, 2)]
>>> print(len(cycle))
2
请注意,这仅返回遇到的第一个循环。若要查找另一个循环,请从图形中删除检测到的循环的边,打破该循环并重复此过程,直到找到所有循环

>>> edges.remove(cycle[0])
>>> ts = ...
>>> get_cycle(ts)
[(5, 3), (4, 5), (3, 4)]

NetworkX可能更简单,所以如果可以的话就使用它吧

你能保证所有元组都是一个循环的一部分吗?这能回答你的问题吗?你能保证所有元组都是一个循环的一部分吗?这能回答你的问题吗?