Suppose I have the following methods:
def read(file: str) -> List[str]: temp = [] with open(file) as f_obj: for line in f_obj: temp.append(line) return temp def append_items_to_list(folders : List[str], file: str): with open(file) as f_obj: for line in f_obj: folders.append(line) def main(): source: str = "source.txt" directories : List[str] = read(file=source) print(len(directories)) folderList : List[str] = [] append_items_to_list(folders=folderList, file=source) print(len(folderList)) if __name__ == '__main__': main() Both methods read from a file, and appends items to a List. The first method creates a temporary List and returns it, while the second accepts a List as a parameter, and appends to it.
Is there a guideline that states which one is preferable? Are there any underlying problems I don't see that I should be concerned about with either one?
I guess you would have to look at why you need to construct a new List, in this case, I don't need to construct a new List, I can just use the second method.
Clarification:
It seems the general answer is to return a new List, but I've narrowed down my problem a little more.
def do_work(source: Path, destination: Path): # do some work with the folders. def create_list_of_empty_folders(folders : List[str], folder: Path): # Check if folder is empty, if so, append it to the List. def cleanup(folders_to_remove: List[Path]): # Remove all folders in the List from the HD. def main(): portableHD = Path("Path\\to\\HD") USB = Path("Path\\to\\USB") empty_folders : List[Path] = [] for folder in portableHD.iterdir(): do_work(source=folder, destination=USB) create_list_of_empty_folders(folders=empty_folders, folder=folder) # Outside of the for loop we can safely remove the empty folders. cleanup(folders_to_remove=empty_folders) if __name__ == '__main__': main() In this context, I have no choice but to pass a List and a folder to my function. Obviously, I could write out the code in the for loop without the use of a function, but let's assume I want to write clean maintainable code.
In my first example, I don't really need to use function, I can read and append the data to a List directly in the main method:
def main(): file: str = "source.txt" folders : List[str] = [] with open(file) as f_obj: for line in f_obj: folders.append(line) if __name__ == '__main__': main() But let's assume more work needs to be done with each of these folders, so I refactor my code and create smaller methods, why is returning a temporary List from a function more desirable?
Does your function really have to know that the goal of the caller is to append ?
Why can't my function know the caller wants to append to a List? After all I did break down the code into smaller functions, one of which appends to a List. Even if I were to rename my method to append(folders : List[str], file: str), the function parameters indicate what I want to append.