如何在函数中处理多个参数?

时间:2018-04-03 10:10:40

标签: python python-3.x python-2.7 search

从功能中过滤掉数据的正确方法是什么?我应该尝试尽可能地压缩所有内容(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)

4 个答案:

答案 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(所有内容都以""结尾,您甚至可以传递一组有效的扩展名)。无论哪种方式,endswithin约束应该如何一起使用,或者扩展是否也应该匹配case_sensitive并不完全清楚。此外,files可能会简化为glob.glob(path + "/*")

但是这些要点并没有改变使用单个列表推导来过滤结果列表的论点。