Python 筛选列表中包含其他列表中任何项目任何部分的任何内容
我想缩短此函数:Python 筛选列表中包含其他列表中任何项目任何部分的任何内容,python,python-2.7,lambda,Python,Python 2.7,Lambda,我想缩短此函数: def get_filenames(path, banned_files=() ): file_list = [] for root, _, files in os.walk(path): BANNED_FILES = banned_files for f in files: for string in BANNED_FILES: if string in f:
def get_filenames(path, banned_files=() ):
file_list = []
for root, _, files in os.walk(path):
BANNED_FILES = banned_files
for f in files:
for string in BANNED_FILES:
if string in f:
continue
path = os.path.join(root, f)
file_list.append(path)
return file_list
这样使用:
filenames = get_filenames(CLIENT_TESTS_PATH, banned_files=['__init__.py', '.pyc', 'accounts.py, otherfile.py'])
这样,来自客户端测试路径的任何文件都不会包含任何被禁止的文件。我不能仅仅通过列表理解来检查文件路径是否在被禁止的文件中,因为我关心是否可以在客户端文件中的任何位置找到任何被禁止的文件。如何使用筛选器、列表理解和/或lambda有效地缩短此时间?我只想要那个目录中的文件,而不是它下面的目录。
多谢各位
为了
我明白了
比如:
banned_files=['__init__.py', '.pyc', 'accounts.py', 'otherfile.py']
file_list = ["""Some list of files here"""]
new_list = {file_name for file_name in file_list for bf in banned_files if bf not in file_name}
这将过滤掉文件名中包含这些字符串的任何内容。这意味着类似my_accounts.py.txt的内容将被阻止。最好把它们分开。例如:
banned_files=['__init__.py', 'accounts.py', 'otherfile.py']
banned_extensions = ['.pyc']
new_list = {file_name for file_name in file_list for ext in banned_extensions if file_name not in banned_files and not file_name.endswith(ext)}
正在编辑以包括os.walk。。。一秒钟。列表理解:
def get_filenames(path, banned_files=()):
return [os.path.join(root, f) for root,_,files in os.walk(path) for f in files]
这与您发布的代码的作用相同,但它可能无法满足您的需要。禁止的文件中的for字符串:循环完全没有用处,因为它所做的只是继续,但继续只在当前循环中工作;它不影响files:loop中的for f,所以内部循环除了浪费处理时间外,什么都不做。要做我认为你想做的事,请执行以下操作:
def get_filenames(path, banned_files=()):
return [os.path.join(root, f)
for root,_,files in os.walk(path)
for f in files
if not any(string in f for string in banned_files)
]
列表理解是最清晰的方式:
[os.path.join(root, f) for root, _, files in os.walk(path) \
for f in files if all([bf not in f for bf in banned_files])]
不要忘记“全部”中的括号:
In [7]: [f for f in ['abc','def','ghi','jkl'] if all([bf not in f \
for bf in ['a','e','z']])]
Out[7]: ['ghi', 'jkl']
In [8]: [f for f in ['abc','def','ghi','jkl'] if all(bf not in f \
for bf in ['a','e','z'])]
Out[8]: ['abc', 'def', 'ghi', 'jkl']
我会这样做:
def get_filenames(path, banned_files=[]):
banned = '|'.join(banned_files)
return [os.path.join(root, f)
for root, _, files in os.walk(path)
for f in files
if f not in banned]
说明:
|不能在文件名中使用,因此我们可以将其用作包含所有禁用文件的字符串的分隔符。根据单个字符串检查找到的文件名要快得多。试试以下方法:
[os.path.join(root, fname) for root, _, fnames in os.path.walk(path) for fname in fnames \
if not any(bad_fname in fname for bad_fname in banned)]
def get_filenames(path, banned_files=()):
file_list = [os.path.join(root, f) for root, _, files in os.walk(path)
for f in files if all(s not in f for s in banned_files)]
return file_list
不要使用可变的默认参数-请参见他的代码,这不是问题,因为OP不会改变参数,也不会尝试返回参数。@zmo-你是对的。这里没有危险。但这仍然不是一个好习惯。元组对于默认值也同样适用。是的,它很少会引起问题。我确实忽略了元组方面。您可能想使用os.walk而不是不推荐的os.path.walk。我喜欢打高尔夫球,但我不理解它。有三个,哈哈,我们能打破它吗down@codyc4321是的,这是一套理解。随着约束的增加,理解会变得非常混乱。然而,单独应用被禁止的文件和扩展名实际上会更快。实际上这不是我所想的,但似乎是最好的。这超出了当前的目录
[os.path.join(root, fname) for root, _, fnames in os.path.walk(path) for fname in fnames \
if not any(bad_fname in fname for bad_fname in banned)]
def get_filenames(path, banned_files=()):
file_list = [os.path.join(root, f) for root, _, files in os.walk(path)
for f in files if all(s not in f for s in banned_files)]
return file_list