使用元组过滤和解包处理空案例

Rei*_*ica 6 python list-comprehension python-2.7 iterable-unpacking

我有一些情况需要根据其中一个列表中的值进行过滤.有时我写这样的东西来过滤它们:

lista = [1, 2, 3]
listb = [7, 8, 9]
filtered_a, filtered_b = zip(*[(a, b) for (a, b) in zip(lista, listb) if a < 3])
Run Code Online (Sandbox Code Playgroud)

这给了filtered_a == (1, 2)filtered_b == (7, 8)

然而,从不断变化的最终状态a < 3,以a < 0导致异常待提高:

Traceback (most recent call last):
  ...
ValueError: need more than 0 values to unpack
Run Code Online (Sandbox Code Playgroud)

我知道为什么会发生这种情况:列表理解是空的,所以就像调用zip(*[])一样zip(),它只返回一个空列表,该列表无法解压缩到单独的filtered_a和filtered_b iterables中.

是否有更好(更短,更简单,更pythonic)的过滤功能来处理空箱?在空的情况下,我希望filtered_a和filtered_b为空迭代,因此任何后续代码都可以保持不变.

Mos*_*oye 5

您可以简单地使用默认值进行短路:

filtered_a, filtered_b = zip(*[(a, b) for a, b in zip(lista, listb) if a < 0]) or ([], [])
print(filtered_b, filtered_a)
# [] []
Run Code Online (Sandbox Code Playgroud)

对于 Python 3,您需要调用list由 返回的迭代器zip,以便第一个操作数可以被计算为空列表(不是迭代器),否则即使迭代器可能为空(因为bool(iter([]))is ) ,也永远不会达到默认值True