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

时间:2016-11-07 15:22:48

标签: python python-2.7 list-comprehension 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])

这会给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

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

是否有更好(更短,更简单,更pythonic)的过滤功能来处理空箱?在空的情况下,我希望filtered_a和filtered_b是空的iterables,所以下面的代码可以保持不变。

2 个答案:

答案 0 :(得分:4)

您可以使用默认值短路

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

对于Python 3,你需要在list返回的迭代器上调用zip,这样第一个操作数就可以被计算为空列表(不是迭代器),否则默认值是由于bool(iter([]))True,所以即使迭代器可能为空,也从未到达。

答案 1 :(得分:1)

我可能会做类似的事情:

lista = [1, 2, 3]
listb = [7, 8, 9]

filtered_abs = ((a, b) for (a, b) in zip(lista, listb) if a < 3])

for a, b in filtered_abs:
    do_thing(a, b)
相关问题