There are 2 versions of the get_startup_folders()
method below, both work as expected and are called only once.
The 1st version has several minor pieces of repeated code which are removed by the use of an inner function in the 2nd version.
I've read several times that the use of inner functions is often frowned on by Python pros, except for in a narrow range of specific cases (e.g. closures and factory functions). I was wondering whether the 2nd version below would be considered superior to the 1st version by experienced Python programmers.
1st version:
def get_startup_folders(self):
folders = []
for item in STARTUP_FOLDERS:
if item == "home":
if self.home_folder not in folders:
folders.append(self.home_folder)
elif item == "file":
if self.file_folder:
if self.file_folder not in folders:
folders.append(self.file_folder)
elif item == "project":
for folder in self.project_folders:
if folder not in folders:
folders.append(folder)
elif item == "user":
for folder in self.user_folders:
if folder not in folders:
folders.append(folder)
# Fail-safe: If empty then use the home folder as a fall back;
# self.home_folder is guaranteed to contain the home folder.
if len(folders) == 0:
folders.append(self.home_folder)
return folders
2nd version:
def get_startup_folders(self):
folders = []
def add_folder(folder):
if folder and folder not in folders:
folders.append(folder)
for item in STARTUP_FOLDERS:
if item == "home":
add_folder(self.home_folder)
elif item == "file":
add_folder(self.file_folder)
elif item == "project":
for folder in self.project_folders:
add_folder(folder)
elif item == "user":
for folder in self.user_folders:
add_folder(folder)
# Fail-safe: If empty then use the home folder as a fall back;
# self.home_folder is guaranteed to contain the home folder.
if len(folders) == 0:
add_folder(self.home_folder)
return folders
1 Answer 1
Use a set
Sets guaranty the unicity of the items it holds, adding the same item twice will result in the second add
doing nothing:
def get_startup_folders(self):
folders = set()
for item in STARTUP_FOLDERS:
if item == "home":
folders.add(self.home_folder)
elif item == "file":
folders.add(self.file_folder)
elif item == "project":
folders.update(self.project_folders)
elif item == "user":
folders.update(self.user_folders)
# Fail-safe: If empty then use the home folder as a fall back;
# self.home_folder is guaranteed to contain the home folder.
if not folders:
folders.add(self.home_folder)
return folders
# or if you trully need a list: return list(folders)
If order matters, there is no such thing as OrderedSet
, but collections.OrderedDict
should be close enough. You just need to handle values that you won't keep:
import itertools
from collections import OrderedDict
def get_startup_folders(self):
folders = OrderedDict()
for item in STARTUP_FOLDERS:
if item == "home":
folders[self.home_folder] = None
elif item == "file":
folders[self.file_folder] = None
elif item == "project":
folders.update(zip(self.project_folders, itertools.repeat(None)))
elif item == "user":
folders.update(zip(self.user_folders, itertools.repeat(None)))
# Fail-safe: If empty then use the home folder as a fall back;
# self.home_folder is guaranteed to contain the home folder.
if not folders:
return [self.home_folder]
return list(folders.keys())
-
\$\begingroup\$ I'm using a list because the order of the added folders must be maintained. \$\endgroup\$mattst– mattst2016年12月30日 19:01:22 +00:00Commented Dec 30, 2016 at 19:01
Explore related questions
See similar questions with these tags.