有以下简单的脚本:
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
等。
答案 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]
我完全希望有人说这种做法非常危险且具体实施 - 我不会对这样的评论提出异议。