省略列表理解中的元素

时间:2015-03-26 13:49:35

标签: python list-comprehension

有以下简单的脚本:

def MyFunction(digit):
    if digit < 4:
        return digit
    else:
        return None

A = [1, 2, 3, 4, 5]
B = [MyFunction(x) for x in A]
print(B) # [1, 2, 3, None, None]

问题:

是否有可能以某种方式重写MyFunction(),因此B在没有[1, 2, 3]的情况下等于None?请不要建议我在列表理解中使用if表达式,在列表理解后处理B等。

3 个答案:

答案 0 :(得分:5)

  

是否有可能以某种方式重写MyFunction(),所以B在没有None的情况下等于[1,2,3]?请不要建议我使用列表理解中的表达式,列表理解后的处理B等

不,不是。列表推导不会改变列表的长度。你无法在MyFunction()中做任何改变。您必须在列表推导中使用if或在列表中进行某种预处理或后处理。

the Python language reference中所述:

  

理解包括单个表达式,后跟至少一个for子句和零个或多个for或if子句。在这种情况下,新容器的元素是通过将每个for或if子句视为块,从左到右嵌套,并评估表达式以生成元素而生成的元素。到达最里面的块的时间。

for次迭代得到一个元素。这是内置于语言中的。

答案 1 :(得分:4)

要过滤元素,您需要使用filter()或列表理解if

即:

B = filter(lambda digit: digit < 4, A)

您可以使用您的函数,但它应该返回布尔值:

def MyFunction(digit):
    if digit < 4:
        return True
    else:
        return False
B = filter(MyFunction, A)

或者简单地说:

def MyFunction(digit):
    return digit < 4

使用列表理解:

B = [digit for digit in A if digit < 4]

答案 2 :(得分:2)

从函数中调整迭代器是可能的,但是很丑陋。不幸的是,我无法摆脱最后的None,但也许其他人可以接受这个想法并对其进行改进。这是我的努力,我扩展了测试数据:

import sys

def MyFunction(digit):
    if digit < 4:
        return digit
    else:
        while digit >= 4:
            try:
                digit = sys._getframe(1).f_locals['.0'].__next__()
            except StopIteration:
                break
        else:
            return digit

A = [6, 7, 1, 2, 3, 4, 5]
B = [MyFunction(x) for x in A]
print(B)

产生

[1, 2, 3, None]

我完全希望有人说这种做法非常危险且具体实施 - 我不会对这样的评论提出异议。