最大值,如果没有值 none - python

max value if no values are none - python

如果满足某些条件,我想 return 列表中的项目。一个条件是我的项目是 "Project A",但另一个条件是 t[1] 不是包含 "Project A" 的所有子列表的 None。我的代码有效,但似乎效率低下。我怎样才能把它结合起来?

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"

由于您无论如何都需要验证所有匹配的条目,因此最好的选择是使用直接的 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'

for循环的else分支仅在for循环完成迭代时执行。仅当在 t[1] 设置为 None.

时发现任何 Project A 条目才会发生这种情况

由于仍有可能匹配项目名称的条目为0条,所以先将found设置为None;当您到达 else 时,它仍然是 None 如果没有要匹配的条目,则阻止循环。

Demo,将发现的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 块中,因为现在使用异常结束函数。

我更喜欢 Martijn 的简单 for 循环,但仅供讨论,您可以使用 key 参数使 None 值成为最大值(如果存在),否则 return条目的最大值:

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 块。

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"

您可以过滤并 return 最大值,如果有任何 None 与 "Project A" 您不应该 return 直接认为没有匹配:

 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)