0

I'm trying to use this function to return two lists using the class dircmp from the filecmp module.

I need to use the lists generated in multiple different parts throughout my code, for now I've been doing this by making the list a global variable.

I would like to know if there is a solution to return both lists that have fully appended after the function is done recursing through sub-directories. This way I don't need to keep creating global variables for every function through my code.

For reference the functions recurse in the same way, but they track a different set of data, for example same_files which need to split into same_leftpath_list and same_rightpath_list.

diff_leftpath_list = []
diff_rightpath_list = []

def print_diff_files(dcmp):

    for name in dcmp.diff_files:
        print("[Differing File] '%s' found in %s and %s" % (name, dcmp.left, 
                                                      dcmp.right))
        diff_leftpath = os.path.join(dcmp.left, name)
        diff_rightpath = os.path.join(dcmp.right, name)
        diff_leftpath_list.append(diff_leftpath)
        diff_rightpath_list.append(diff_rightpath)

    for sub_dcmp in dcmp.subdirs.values():
        print_diff_files(sub_dcmp)

print_diff_files(dcmp)
print diff_leftpath_list
Paul Rooney
  • 20,879
  • 9
  • 40
  • 61
  • 2
    Not quite sure I understand what you're looking for, but can you just add the two lists as parameters to the function and keep passing them through, ultimately returning them? – ZaxR Jun 13 '18 at 02:51
  • You can return both at one time. You can make them in to a tuple and return that. See [here](https://stackoverflow.com/questions/38508/whats-the-best-way-to-return-multiple-values-from-a-function-in-python). – Paul Rooney Jun 13 '18 at 03:38

1 Answers1

0

There are two common ways of solving your problem: passing in the lists as parameters and merging return values from the recursive calls.

Here's how you could pass the lists as parameters. We create a wrapper function to hide that implementation detail.

def print_diff_files(dcmp):
    """calls the wrapper to do the real work.  Hides the list management."""
    left = []
    right = []
    _print_diff_files_impl(dcmp, left, right)
    return left, right

def _print_diff_files_impl(dcmp, diff_leftpath_list, diff_rightpath_list):
    for name in dcmp.diff_files:
        print("[Differing File] '%s' found in %s and %s" % (name, dcmp.left, 
                                                      dcmp.right))
        diff_leftpath = os.path.join(dcmp.left, name)
        diff_rightpath = os.path.join(dcmp.right, name)
        diff_leftpath_list.append(diff_leftpath)
        diff_rightpath_list.append(diff_rightpath)
    for sub_dcmp in dcmp.subdirs.values():
        _print_diff_files_impl(sub_dcmp, diff_leftpath_list, diff_rightpath_list)

Here's how you could manage it with return values. This is usually a better approach.

def print_diff_files(dcmp):
    left = []
    right = []
    for name in dcmp.diff_files:
        print("[Differing File] '%s' found in %s and %s" %
              (name, dcmp.left, dcmp.right))
        diff_leftpath = os.path.join(dcmp.left, name)
        diff_rightpath = os.path.join(dcmp.right, name)
        left.append(diff_leftpath)
        right.append(diff_rightpath)
    for sub_dcmp in dcmp.subdirs.values():
        new_left, new_right = print_diff_files(sub_dcmp)
        left.extend(new_left)
        right.extend(new_right)
    return left, right

If you want to get fancier, you can use generators, but that's a slightly bigger change to your code.

Mr Fooz
  • 109,094
  • 6
  • 73
  • 101