从功能中过滤掉数据的正确方法是什么?我应该尝试尽可能地压缩所有内容(search_query),还是每次有新参数需要包含时都应该过滤列表(search_query2)。我有更多的论据,我更加困惑如何处理这个问题。例如:
import os
query = ""
my_path = os.getcwd()
def search_query(query, path, extensions_only=False, case_sensitive=False):
results = []
if extensions_only is True:
for f in os.listdir(path):
if case_sensitive:
if f.endswith(query):
results.append(os.path.join(path, f))
else:
if f.endswith(query):
results.append(os.path.join(path, f).lower())
elif case_sensitive is not True:
for f in os.listdir(path):
if query.lower() in f.lower():
results.append(os.path.join(path, f))
return results
results = search_query("_c", my_path)
print(results)
# Alternative way to deal with this
def search_query2(query, path, extensions_only=False, case_sensitive=False):
results = []
for f in os.listdir(path):
results.append(os.path.join(path, f))
if extensions_only:
filtered_lst = []
for part in results:
if part.endswith(query):
filtered_lst.append(part)
results = filtered_lst
if case_sensitive:
filtered_lst = []
for part in results:
if query in part:
filtered_lst.append(part)
results = filtered_lst
elif not case_sensitive:
filtered_lst = []
for part in results:
if query.lower() in part.lower():
filtered_lst.append(part)
results = filtered_lst
print(results)
return results
search_query2("pyc", my_path, case_sensitive=True)
答案 0 :(得分:2)
没有一个适合所有人"正确"做这样的事情的方式。另一种选择是将单独的函数或私有子函数作为包装器调用。
在您的具体情况下,有一些方法可以优化您想要做的事情,以使其更清晰。
你做了很多
x = []
for i in y:
if cond(i):
x.append(i)
y = x
这被称为过滤器,python有两种方法可以在一行中执行此操作
y = list(filter(cond, y)) # the 'functional' style
或
y = [i for i in y if cond(i)] # comprehension
使事情变得更加清晰。你写的映射有类似的东西:
x = []
for i in y:
x.append(func(i))
y = x
# instead do:
y = list(map(func, y)) # functional
# or
y = [func(i) for i in y] # comprehension
我们还可以组合地图和过滤器:
x = list(map(func, filter(cond, y)))
x = [func(i) for i in y if cond(i)]
使用这些我们可以连续构建许多过滤器和地图,同时保持我们正在做的事情。这是functional programming的优势之一。
我已修改您的代码以使用generator expressions,这只会在我们致电list(results)
时才会在最后评估,从而节省了大量浪费时间,每次都会制作新列表:
def search_query2(query, path, extensions_only=False, case_sensitive=False):
results = (os.path.join(path, f) for f in os.listdir(path))
if extensions_only:
results = (part for part in results if part.endswith(query))
elif case_sensitive: # I'm pretty sure this is actually the logic you want
results = (part for part in results if query in part)
else:
results = (part for part in results if query.lower() in part.lower())
return list(results)
答案 1 :(得分:0)
您想过滤所有相同类型的文件吗?您可以使用glob模块执行此操作。 例如
import glob
# Gets all the images in the specified directory.
print(glob.glob(r"E:/Picture/*/*.jpg"))
# Gets all the .py files from the parent directory.
print glob.glob(r'../*.py')
答案 2 :(得分:0)
我喜欢"准备"我的条件一开始就让事情变得干净整洁,让以后更轻松。确定不同参数对代码的影响。在这种情况下," case_sensitive"定义你使用f.lower()与否,以及"扩展"正在定义你的比较方法。 在这种情况下,我会写这样的东西。
def search_query(query, path, extensions_only=False, case_sensitive=False):
results = []
for f in os.listdir(path):
if case_sensitive is True:
fCase=f.lower()
queryCase = query.lower()
elif case sensitive is False:
fCase = f
queryCase = query
if extensions_only is True:
if f.endswith(query):
results.append(os.path.join(path, f))
elif extensions_only is False:
if query in f:
results.append(os.path.join(path, f))
return results
results = search_query("_c", my_path)
print(results)
这允许我定义每个结果对不同级别的函数的影响,而不会让它们嵌套并且有点令人头疼以便跟踪!
答案 3 :(得分:0)
另一种可能性:你可以使用单个条件列表理解:
def search_query2(query, path, extensions_only=False, case_sensitive=False):
files = [os.path.join(path, f) for f in os.listdir(path)]
result = [part for part in files
if (not extensions_only or part.endswith(query)) and
(query in part if case_sensitive
else query.lower() in part.lower())]
print(results)
return results
这可能看起来非常密集"起初难以理解,但恕我直言,它使得非常清楚(甚至比你的变量名更清楚)所有这些条件仅仅是过滤而且从不更改结果列表的实际元素。
此外,正如评论中所述,您可以使用默认参数extension=""
而不是extensions_only
(所有内容都以""
结尾,您甚至可以传递一组有效的扩展名)。无论哪种方式,endswith
和in
约束应该如何一起使用,或者扩展是否也应该匹配case_sensitive
并不完全清楚。此外,files
可能会简化为glob.glob(path + "/*")
。
但是这些要点并没有改变使用单个列表推导来过滤结果列表的论点。