简体   繁体   English

什么是最好的:这个 python function 中的全局变量或参数?

[英]What is best: Global Variable or Parameter in this python function?

I have a question about the following code, but i guess applies to different functions.我对以下代码有疑问,但我想适用于不同的功能。 This function computes the maximum path and its length for a DAG, given the Graph, source node, and end node.这个 function 在给定 Graph、源节点和结束节点的情况下计算 DAG 的最大路径及其长度。

To keep track of already computed distances across recursions I use "max_distances_and_paths" variable, and update it on each recursion.为了跟踪已经计算的递归距离,我使用“max_distances_and_paths”变量,并在每次递归时更新它。

Is it better to keep it as a function parameter (inputed and outputed across recursions) or use a global variable and initialize it outside the function?最好将其保留为 function 参数(通过递归输入和输出)还是使用全局变量并在 function 之外对其进行初始化?

How can avoid to have this parameter returned when calling the function externally (ie it has to be outputed across recursions but I dont care about its value, externally)?如何避免在外部调用 function 时返回此参数(即它必须跨递归输出,但我不关心它的值,外部)?

a better way than doing: LongestPath(G, source, end)[0:2]??比这样做更好的方法:LongestPath(G, source, end)[0:2]??

Thanks谢谢

# for a DAG computes maximum distance and maximum path nodes sequence (ordered in reverse).
# Recursively computes the paths and distances to edges which are adjacent to the end node
# and selects the maximum one
# It will return a single maximum path (and its distance) even if there are different paths
# with same max distance
# Input {Node 1: adj nodes directed to Node 1 ... Node N: adj nodes directed to Node N}
# Example: {'g': ['r'], 'k': ['g', 'r']})
def LongestPath(G, source, end, max_distances_and_paths=None):
    if max_distances_and_paths is None:
        max_distances_and_paths = {}
    max_path = [end]
    distances_list = []
    paths_list = []
    # return max_distance and max_path from source to current "end" if already computed (i.e.
    # present in the dictionary tracking maximum distances and correspondent distances)
    if end in max_distances_and_paths:
        return max_distances_and_paths[end][0], max_distances_and_paths[end][1], max_distances_and_paths
    # base case, when end node equals source node
    if source == end:
        max_distance = 0
        return max_distance, max_path, max_distances_and_paths
    # if there are no adjacent nodes directed to end node (and is not the source node, previous case)
    # means path is disconnected
    if len(G[end]) == 0:
        return 0, [0], {"": []}
    # for each adjacent node pointing to end node compute recursively its max distance to source node
    # and add one to get the distance to end node. Recursively add nodes included in the path
    for t in G[end]:
        sub_distance, sub_path, max_distances_and_paths = LongestPath(G, source, t, max_distances_and_paths)
        paths_list += [[end] + sub_path]
        distances_list += [1 + sub_distance]
    # compute max distance
    max_distance = max(distances_list)
    # access the same index where max_distance is, in the list of paths, to retrieve the path
    # correspondent to the max distance
    index = [i for i, x in enumerate(distances_list) if x == max_distance][0]
    max_path = paths_list[index]
    # update the dictionary tracking maximum distances and correspondent paths from source
    # node to current end node.
    max_distances_and_paths.update({end: [max_distance, max_path]})
    # return computed max distance, correspondent path, and tracker
    return max_distance, max_path, max_distances_and_paths

Global variables are generally avoided due to several reasons (see Why are global variables evil? ).由于几个原因,通常避免使用全局变量(请参阅为什么全局变量是邪恶的? )。 I would recommend sending the parameter in this case.我建议在这种情况下发送参数。 However, you could define a larger function housing your recursive function.但是,您可以定义一个更大的 function 来容纳递归 function。 Here's a quick example I wrote for a factorial code:这是我为阶乘代码编写的一个简单示例:

def a(m):
    def b(m):
        if m<1:return 1
        return m*b(m-1)
    n = b(m)
    m=m+2
    return n,m
print(a(6))

This will give: (720, 8) .这将给出: (720, 8) This proves that even if you used the same variable name in your recursive function, the one you passed in to the larger function will not change.这证明即使您在递归 function 中使用相同的变量名,您传递给较大的 function 的变量名也不会改变。 In your case, you want to just return n as per my example.在您的情况下,您只想按照我的示例返回n I only returned an edited m value to show that even though both a and b functions have m as their input, Python separates them.我只返回了一个编辑过的m值,以表明即使ab函数都将m作为输入,Python 将它们分开。

In general I would say avoid the usage of global variables.一般来说,我会说避免使用全局变量。 This is because is makes you code harder to read and often more difficult to debug if you codebase gets a bit more complex.这是因为如果您的代码库变得更复杂一些,这会使您的代码更难阅读并且通常更难以调试。 So it is good practice.所以这是一个很好的做法。

I would use a helper function to initialise your recursion.我会使用一个助手 function 来初始化你的递归。

def longest_path_helper(G, source, end, max_distances_and_paths=None):
    max_distance, max_path, max_distances_and_paths = LongestPath(
        G, source, end, max_distances_and_paths
    )
    return max_distance, max_path, max_distances_and_paths

On a side note, in Python it is convention to write functions without capital letters and separated with underscores and Capicalized without underscores are used for classes.附带说明一下,在 Python 中,编写不带大写字母并用下划线分隔的函数是惯例,类使用不带下划线的 Capicalized。 So it would be more Pythonic to use def longest_path():所以使用def longest_path():

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM