python - python 列表推导式总是一种好的编程习惯吗?

标签 python coding-style list-comprehension

为了让问题更清楚,我将使用一个具体的例子。

我有一个大学类(class)列表,每个类(class)都有几个字段(所有字段都是字符串)。用户给我一串搜索词,我返回与所有搜索词匹配的类(class)列表。这可以通过单个列表理解或几个嵌套的 for 循环来完成。

这是实现。一、Course类:

class Course:
    def __init__(self, date, title, instructor, ID, description, instructorDescription, *args):
        self.date = date
        self.title = title
        self.instructor = instructor
        self.ID = ID
        self.description = description
        self.instructorDescription = instructorDescription
        self.misc = args

每个字段都是一个字符串,除了 misc ,这是一个字符串列表。

这是作为单个列表理解的搜索。 courses是类(class)列表,query是搜索词的字符串,例如“历史项目”。

def searchCourses(courses, query):
    terms = query.lower().strip().split()
    return tuple(course for course in courses if all(
            term in course.date.lower() or
            term in course.title.lower() or
            term in course.instructor.lower() or
            term in course.ID.lower() or
            term in course.description.lower() or
            term in course.instructorDescription.lower() or
            any(term in item.lower() for item in course.misc)
        for term in terms))

您会注意到复杂的列表理解很难阅读。

我实现了与嵌套 for 循环相同的逻辑,并创建了这个替代方案:

def searchCourses2(courses, query):
    terms = query.lower().strip().split()
    results = []
    for course in courses:
        for term in terms:
            if (term in course.date.lower() or
                term in course.title.lower() or
                term in course.instructor.lower() or
                term in course.ID.lower() or
                term in course.description.lower() or
                term in course.instructorDescription.lower()):
                break
            for item in course.misc:
                if term in item.lower():
                    break
            else:
                continue
            break
        else:
            continue
        results.append(course)
    return tuple(results)

这种逻辑也很难遵循。我已经验证这两种方法都返回正确的结果。

除某些情况外,这两种方法的速度几乎相同。我用 timeit 进行了一些测试,发现当用户搜索多个不常见术语时,前者的速度快了三倍,而当用户搜索多个常见术语时,后者的速度快了三倍。不过,这并没有大到足以让我担心。

所以我的问题是:哪个更好?列表推导式是否始终是正确的选择,还是应该使用嵌套的 for 循环来处理复杂的语句?或者有更好的解决方案吗?

最佳答案

恕我直言,当它们比替代方案更清晰(或者至少不那么清晰)并且更简洁时,它们就是很好的编程实践。在这种情况下,这两种选择都不那么明确。就我个人而言,我会将搜索逻辑放在 Course 类中。这对我来说更有意义,因为逻辑与类相关联。

class Course:
    def __init__(self, date, title, instructor, ID, description, instructorDescription, *args):
        self.date = date
        self.title = title
        self.instructor = instructor
        self.ID = ID
        self.description = description
        self.instructorDescription = instructorDescription
        self.misc = args

    def matches_term(self, term):
        if term in self.date.lower():
            return True
        # etc
        return False

然后您可以使用更简单的生成器(或列表)表达式进行搜索:

def searchCourses(courses, query):
    terms = query.lower().strip().split()
    return tuple(course for course in courses
                 if all(course.matches_term(term)
                        for term in terms)
                )

一个简单的测试:

courses = (
    Course("today", "", "", "", "", ""),
    Course("wednesday", "", "", "", "", ""),
    Course("today", "", "", "", "", ""),
    Course("sunday", "", "", "", "", ""),
)

results = searchCourses(courses, "on today or wednesday")
for course in results:
    print course.date

输出:

today
wednesday
today

关于python - python 列表推导式总是一种好的编程习惯吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8176168/

相关文章:

python - NLTK 解析树中的转义括号

Python:计算if条件列表中元素的数量

Python列表理解覆盖值

python - 如何在列表理解中使用条件表达式(带有 if 和 else 的表达式)?

python - 使用 anaconda scipy 对角化大型矩阵时出错

Python 向 "1"= ="1"返回 false。任何想法为什么?

python - 使用方法调用在 Python 中格式化多行

c++ - 您会推荐 Todd Hoff 的《C++ 编码标准》吗?

c - break in a case with return.. 和默认

python - 使用列表理解来存储最大可见值