为了让问题更清楚,我将使用一个具体的例子。
我有一个大学类(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/