【发布时间】:2011-11-18 00:07:42
【问题描述】:
为了让问题更清楚,我将使用一个具体的例子。
我有一个大学课程列表,每门课程都有几个字段(都是字符串)。用户给了我一串搜索词,我返回一个与所有搜索词匹配的课程列表。这可以在单个列表理解或几个嵌套的 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 是课程列表,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 循环来处理复杂的语句?还是有更好的解决方案?
【问题讨论】:
-
在您显示的代码中没有一个列表理解——可能您的意思是 generator expressions 代替。
-
作为一般规则:如果它难以阅读,那就是个坏主意。
-
False not in <iterable>在 Python 中被称为all()。 -
@julio 我知道这是讨厌的代码;它不可读。这就是我来这里寻求帮助的原因。欢迎提出建议。
标签: python coding-style list-comprehension