Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在csv文件中查找所有可能的路径_Python_List_Python 3.x_Csv_Path - Fatal编程技术网

Python 在csv文件中查找所有可能的路径

Python 在csv文件中查找所有可能的路径,python,list,python-3.x,csv,path,Python,List,Python 3.x,Csv,Path,我有一个csv文件,其格式如下: header1,header2,header3,header4 1,4,2,5 1,4,0,5 0,4,2,5 我的问题的相关信息仅在第1栏和第3栏中。我试图在这个csv文件中找到所有可能的路径,如果两个值在同一行中,那么它们在一个定向路径中连接。例如,在上述数据中: 1 is connected to 2 1 is connected to 0 0 is connected to 2 那么所有可能的路径都是: [1,2] [1,0,2] [0,2] 特别

我有一个csv文件,其格式如下:

header1,header2,header3,header4
1,4,2,5
1,4,0,5
0,4,2,5
我的问题的相关信息仅在第1栏和第3栏中。我试图在这个csv文件中找到所有可能的路径,如果两个值在同一行中,那么它们在一个定向路径中连接。例如,在上述数据中:

1 is connected to 2
1 is connected to 0
0 is connected to 2
那么所有可能的路径都是:

[1,2]
[1,0,2]
[0,2]
特别是在在线资源的帮助下,我已经能够找到指定起始节点和结束节点的所有路径。以下是我的代码:

import csv  
def main():
   inputFile = "file_directory"
   a =[]
   with open(inputFile) as csvfile:
      reader = csv.reader(csvfile)
      next(reader)
      for line in reader:
         a.append([line[0], line[2]])
   # This will print all the paths starting with 1 and ending with 2
   print(str(getAllSimplePaths('1', '2', a)))


def getAllSimplePaths(originNode, targetNode, a):
      return helpGetAllSimplePaths(targetNode,
                         [originNode],
                         set(originNode),
                         a,
                         list())


def helpGetAllSimplePaths(targetNode, currentPath, usedNodes, a, answerPaths):
  lastNode = currentPath[-1]
  if lastNode == targetNode:
    answerPaths.append(list(currentPath))
  else:
    for elem in a:
      if elem[0] == lastNode:
        if elem[1] not in usedNodes:
          currentPath.append(elem[1])
          usedNodes.add(elem[1])
          helpGetAllSimplePaths(targetNode,currentPath,usedNodes,a,answerPaths)
          usedNodes.remove(elem[1])
          currentPath.pop()
  return answerPaths               


if __name__ == '__main__':
   main()
运行此操作时,我正确地得到以下结果:

[['1', '2'], ['1', '0', '2']]
但是,我真正想做的是能够循环遍历csv文件第二列中的所有元素,并找到每个元素的所有可能路径。这件事我已经做了好几天了,我想不出一个办法。我的csv文件大约有2000行。如有任何帮助/建议,将不胜感激!谢谢大家!

更新:额外信息

csv文件中的每一行都已经是两个元素之间的路径。因此,我拥有的路径数将等于我在csv文件中拥有的行数。现在,从我问题示例中的第一行开始,1与2相连,因此['1','2']是一条路径。对于每一行,我想通过查看第三列elem2中的同一行,然后在csv文件中的所有行中搜索第一列中的elem2,找到第一列中的元素elem1连接到的内容。如果某行的第一列中存在elem2,则elem2必须连接到同一行第三列elem3中的相应元素。在这种情况下,我们的路径是[elem1,elem2,elem3]。类似地,对于elem3,我必须查看所有行,以查看它是否存在于第一列中。如果它不存在,那么第一条路就完了。接下来我转到第二条路径

上述示例所需的输出如下所示:

[['1','2'], ['1', '0', '2'], ['0', '2'], ['1','0']]
我正在使用Python 3.5.1。

这是一个我优化了一点的版本。在您将其用于一个非常大的csv文件之前,我建议您删除它所做的一些/大部分打印,这不会影响最终结果

import csv
from pprint import pprint, pformat

def main():
    inputFile = "paths.csv"
    with open(inputFile, newline='') as csvfile:
       reader = csv.reader(csvfile)
       next(reader)
       a = [[row[0], row[2]] for row in reader]
    print('a:\n', pformat(a))

    # construct an adjacency *dictionary*
    nodeToNodes = {}
    for src, dst in a:
        nodeToNodes.setdefault(src, []).append(dst)
    print('\nnodeToNodes:\n', pformat(nodeToNodes))

    print('\ngathering results:')
    all_paths = []
    for src, dst in a:
        print('  {} <-> {}'.format(src, dst))
        more_paths = getAllSimplePaths(dst, [src], {src}, nodeToNodes, [])
        print('    {}'.format(pformat(more_paths)))
        all_paths.extend(more_paths)

    print('\nall paths: {}'.format(pformat(all_paths)))

def getAllSimplePaths(targetNode, currentPath, usedNodes, nodeToNodes, answerPaths):
    lastNode = currentPath[-1]
    if lastNode == targetNode:
        answerPaths.append(currentPath[:])
    elif lastNode in nodeToNodes:
        for neighbor in nodeToNodes[lastNode]:
            if neighbor not in usedNodes:
                currentPath.append(neighbor)
                usedNodes.add(neighbor)
                getAllSimplePaths(targetNode, currentPath, usedNodes, nodeToNodes,
                                  answerPaths)
                usedNodes.remove(neighbor)
                currentPath.pop()

    return answerPaths

if __name__ == '__main__':
   main()
输出:

a: [['1', '2'], ['1', '0'], ['0', '2']] 节点节点: {'0': ['2'], '1': ['2', '0']} 收集结果: 1 2 [['1', '2'], ['1', '0', '2']] 1 0 [['1', '0']] 0 2 [['0', '2']] 所有路径:['1','2'],['1','0','2'],['1','0'],['0','2']]
是否存在循环的可能性,例如,是否存在1连接到0且0连接到1的情况?如果是,在这种情况下,期望的输出是什么?是的,有循环的可能性。但是,上面的代码旨在检测这种情况,并且不允许循环发生。例如,如果1连接到2,2连接到1,那么程序将只输出[['1','2']],因为1是开始节点,2是结束节点。首先,我建议您修复问题中代码的缩进。此外,每个元素的所有可能路径都意味着从什么到什么的路径?如果不仔细考虑代码和天真的问题,这可能还为时过早,但我想到,存储位置信息可能很有价值。我将回顾您的代码,但现在,使用您的示例,说col1:1连接到col3:2,col1:1连接到col3:0,col1:0连接到col3:2是否有价值,因此,col1:1连接到col3:2,col1:1连接到col3:0,col3:2,col1:0连接到col3:2?无论这是否增加了价值,我是否正确地解释了您示例中的可能路径?@martineau right,我已经更新了它。谢谢谢谢这适用于小型csv文件。我尝试将它应用于我的csv文件,该文件有2000行,并且运行无限。有没有更有效的方法?不客气。我注意到,由于在main中的last for循环中进行了打印,因此对同一对节点调用了两次getAllSimplePath函数。我已经从我的答案中删除了这一点,这将使它更快。不知道你的2000行csv文件需要多少钱,不过…我已经做了一些优化来加速它。如果你想通过下载链接提供2000行的csv文件,我会看看如果速度仍然太慢,我还能做些什么。