繁体   English   中英

具体情况下Python中的列表理解

[英]List comprehension in Python under specific circumstances

lst_a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
lst_b = [[1, 4, 7], [6, 5, 4], [9, 8, 7]]

我的目标是检查lst_a中的所有嵌套列表,如果第一个条目 == lst_b中任何元素的第一个条目。 如果不是只复制那个子列表。 在这个例子中,他不会复制lst_a[0]而是复制 1 和 2。

我试图通过列表理解来实现我的目标,但它不起作用。

zero = [x[0] for x in lst_a]
if zero not in lst_b:
    # I don't know what to do here.

创建元组或字典是不可能的,因为整个过程处于循环中,每秒钟都有新数据进入,我尽量避免将重复项复制到列表中。

编辑: lst_b在整个过程之后应该看起来像这样:

lst_b = [[1, 4, 7], [6, 5, 4], [9, 8, 7], [4, 5, 6], [7, 8, 9]]

lst_b中的所有第一个元素提取到一个集合中,以便您可以有效地检查成员资格。 然后使用列表推导复制lst_a中符合您的条件的所有子列表。

first_elements = {x[0] for x in lst_b}
result = [x for x in lst_a if x[0] not in first_elements]

这有点拗口,但还不错:

lst_b.extend(x for x in lst_a if not any(x[0] == y[0] for y in lst_b)

如果您想要一个列表而不是就地修改lst_b ,那么

lst_c = lst_b + [x for x in lst_a if not any(x[0] == y[0] for y in lst_b)]

无论哪种情况,我们都会检查lst_a中的每个子列表x 如果子列表的第一个元素等于lst_b中任何子列表的第一个元素,则any(x[0] == y[0] for y in lst_b)True 如果这不是真的,那么我们将在最终结果中包含x

当找到一个匹配项就足够时,使用any可以避免检查lst_b中的每个子列表。 (在某些情况下,这可能比首先创建一整套第一元素更有效,如@barmar 的回答,但平均而言,这种方法可能更有效。)

可能有更有效的方法可以做到这一点,但这可以实现目标。

>>> [a for a in lst_a if a[0] not in [b[0] for b in lst_b]]
[[4, 5, 6], [7, 8, 9]]

另一种方式:

exclude=set(next(zip(*lst_b))) 
lst_b+=[sl for sl in lst_a if sl[0] not in exclude]
>>> lst_b
[[1, 4, 7], [6, 5, 4], [9, 8, 7], [4, 5, 6], [7, 8, 9]]

解释:

  1. zip(*lst_b)是矩阵lst_b的逆矩阵的生成器, *扩展子列表,这将创建一个生成器,产生[(1, 6, 9), (4, 5, 8), (7, 4, 7)]依次。
  2. next(zip(*lst_b)我们只需要那个逆的第一个元素: (1,6,9)
  3. set(next(zip(*lst_b)))只需要其中的 uniq 元素,因此变成一个集合。 你得到{1, 6, 9} (顺序无关紧要)
  4. [sl for sl in lst_a if sl[0] not in exclude]在该条件下过滤。
  5. lst_b+=使用过滤后的元素扩展lst_b

利润!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM