以下代码中 'or' 关键字的用途是什么?

What is the use of the 'or' keyword in the following code?

我无法理解以下代码中 or 关键字的用法,该代码取自 answer from this site,显示了使用 reduce 对列表进行分区的一种方法:

 def partition(l, p):
     return reduce(lambda x, y: x[not p(y)].append(y) or x, l, ([], []))

我知道如果条件为真,代码将附加到第一个列表,否则附加到第二个。 or x 部分的作用是什么?我尝试将其排除在外,但最终出现错误 TypeError: 'NoneType' object is not subscriptable

有人在打代码。 list.append() always returns None,这是一个假值。通过使用 or 他们可以得到 lambda return 第二个表达式的结果; None or ... 始终 return 是 ... 的结果。

您可以用完整的函数定义替换 lambda

def func(x, y): 
    x[not p(y)].append(y)
    return x

和上面的lambda都重新定义了return的x参数,也就是每次调用传递的累计值reduce()。在这种情况下,它是一个包含两个列表的元组,分区值被收集到其中。

就个人而言,我只是使用了一个循环:

def partition(l, p):
    a, b = [], []
    for v in l:
        target = a if not p(v) else b
        target.append(v)
    return a, b

毕竟,可读性很重要。此外,因为它避免了额外的函数调用(输入列表中每个值一个额外的调用),它也快了很多:

>>> import timeit
>>> import random
>>> testdata = [random.randrange(1000) for _ in range(10 ** 4)]
>>> predicate = lambda v: v % 2 == 0
>>> def partition_lambda(l, p):
...     return reduce(lambda x, y: x[not p(y)].append(y) or x, l, ([], []))
...
>>> def partition_readable(l, p):
...     a, b = [], []
...     for v in l:
...         target = a if not p(v) else b
...         target.append(v)
...     return a, b
...
>>> timeit.timeit('part(l, p)', 'from __main__ import partition_lambda as part, testdata as l, predicate as p', number=10**3)
2.5286515180487186
>>> timeit.timeit('part(l, p)', 'from __main__ import partition_readable as part, testdata as l, predicate as p', number=10**3)
1.6824414430302568

因此对于 10k 项目列表的分区,1000 次,可读版本只需要 reduce() 版本所花费时间的 2/3。