我有两个列表:
listA = [230, 232, 230, 229, 237, 212, 245, 233, 220, 230]
listB = [232, 231, 234, 230, 234, 228, 244, 236, 227, 229]
如何比较列表,并且仅将listA
大于listB
的点返回到第三个列表listC
,同时保留索引,以便结果如下所示:
listC = [ , 232, , , 237, , 245, , , 230]
毕竟,还有第四个列表listD
:
listD = [1,2,3,4,5,6,7,8,9,10]
我正在尝试将其与listC
进行整理,以便我最终在索引方面获得列表 C 和 D 匹配:
最终结果:
listD = [ 2 , 5 , 7 , 10]
listC = [233,237,245,230]
我正在研究列表理解,因为我被告知它会有所帮助,但我不确定如何应用我所读的内容。
这是itertools.compress
的完美用例:
>>> from itertools import compress, starmap
>>> from operator import gt
获取一个新的布尔值列表,其中True
表示listA
中的项大于listB
中的相应项。
>>> bools = list(starmap(gt, zip(listA, listB)))
>>> bools
[False, True, False, False, True, False, True, False, False, True]
现在我们使用compress
根据bools
过滤listA
和listD
。
>>> list(compress(listA, bools))
[232, 237, 245, 230]
>>> list(compress(listD, bools))
[2, 5, 7, 10]
我不会在这里使用列表理解; 您正在构建两个列表,而不是一个列表,使用常规for
循环会更容易:
listC = []
listD_filtered = []
for a, b, d in zip(listA, listB, listD):
if a > b:
listC.append(a)
listD_filtered.append(d)
使用zip()
您可以并行迭代列表,完全无需跟踪索引。
您仍然可以在此处使用推导式,但随后您将构建一个包含(a, d)
值的序列,然后再次使用zip()
将该结果拆分为两个单独的列表:
listC, listD = zip(*((a, d) for a, b, d in zip(listA, listB, listD) if a > b))
然而,这变得更难理解和解释,在这种情况下,你实际上有元组,而不是列表(根据您的用例,您必须再次将它们转换为列表(。
演示:
>>> listA = [230, 232, 230, 229, 237, 212, 245, 233, 220, 230]
>>> listB = [232, 231, 234, 230, 234, 228, 244, 236, 227, 229]
>>> listD = [1,2,3,4,5,6,7,8,9,10]
>>> listC = []
>>> listD_filtered = []
>>> for a, b, d in zip(listA, listB, listD):
... if a > b:
... listC.append(a)
... listD_filtered.append(d)
...
>>> listC
[232, 237, 245, 230]
>>> listD_filtered
[2, 5, 7, 10]
>>>
>>> listC, listD = zip(*((a, d) for a, b, d in zip(listA, listB, listD) if a > b))
>>> listC
(232, 237, 245, 230)
>>> listD
(2, 5, 7, 10)
通过列表推导得到结果:
In [6]: listC = [i for i, j in zip(listA, listB) if i>j]
In [7]: listC
Out[7]: [232, 237, 245, 230]
In [9]: listD = [i for i, (a, b) in enumerate(zip(listA, listB), 1) if a>b]
In [10]: listD
Out[10]: [2, 5, 7, 10]