如果满足某些条件,我想在列表中返回一个项目。一个条件是我的项目是"Project A"
,但另一个条件是t[1]
对于包含None
的所有子列表都不是"Project A"
。我的代码有效,但似乎效率低下。我怎样才能把它结合起来?
mylist = [(1, None, "Project A"), (2, 3, "Project A"), (3, 6, "Project B")]
try:
if None not in [t[1] for t in mylist if t[2] == "Project A"]:
print max(t for t in mylist if t[2] == "Project A" and t[1] is not None)
else:
print "no match"
except ValueError:
print "no match"
答案 0 :(得分:1)
由于您无论如何都需要验证所有匹配的条目,因此最佳选择是使用直接for
循环;在未达到None
条件时爆发:
found = None
for entry in mylist:
if entry[2] == 'Project A':
if entry[1] is None:
print 'No match'
break
if not found or entry > found:
found = entry
else:
# only executed when there was no break!
print found or 'No match'
else
循环的for
分支仅在for
循环完成迭代时执行。只有在Project A
被设置为t[1]
的情况下找到None
个条目时才会发生这种情况。
由于仍有可能存在与项目名称匹配的0个条目,因此found
首先设置为None
;如果没有匹配的条目,那么当您到达None
阻止循环时,它仍为else
。
演示,将找到的None
案例转换为例外以显示差异:
>>> def find_max_project(projects, target):
... found = None
... for entry in projects:
... if entry[2] == target:
... if entry[1] is None:
... raise ValueError('no match')
... if not found or entry > found:
... found = entry
... else:
... return found
...
>>> find_max_project([(1, None, "Project A"), (2, 3, "Project A"), (3, 6, "Project B")], 'Project A')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 7, in find_max_project
ValueError: 'no match'
>>> find_max_project([(1, 4, "Project A"), (2, 3, "Project A"), (3, 6, "Project B")], 'Project A')
(2, 3, 'Project A')
>>> find_max_project([(1, 2, "Project A"), (1, 3, "Project A")], 'Project A')
(1, 3, 'Project A')
>>> find_max_project([(1, 2, "Project B"), (1, 3, "Project B")], 'Project A')
>>> find_max_project([(1, 2, "Project B"), (1, 3, "Project B")], 'Project A') is None
True
请注意,在这个版本中,我们甚至不需要将最后一行放在else
块中,因为使用异常现在会结束该函数。
答案 1 :(得分:1)
tmp = [x for x in mylist if x[2] == "Project A"]
if tmp and None not in zip(*tmp)[1]:
print max(tmp)
else:
print "no match"
答案 2 :(得分:1)
您可以过滤并返回最大值,如果有"Project A"
的任何无,您不应该立即返回没有匹配项:
def filtered(l,proj):
filt = []
for t in l:
if t[2] == proj:
if t[1] is None:
return "No match"
filt.append(t)
return max(filt)
答案 3 :(得分:0)
我更喜欢Martijn的简单for
循环,但仅供讨论,您可以使用key
参数将None
值设为最大值(如果存在),否则返回最大值条目:
try:
result = max((t for t in mylist if t[2] == "Project A"),
key=lambda x: (x[1] is None, x))
print 'no match' if result[1] == None else result
except ValueError:
print 'no match'
如果您确保Project A
在列表中,那么您可以摆脱try块。