Имам два списъка:
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]
Търсех разбирането на списъка, както ми казаха, че ще помогне, но не съм сигурен как да прилагам това, което съм прочел.
Отговори:
3 за отговор № 1Това е идеалният случай за употреба itertools.compress
:
>>> from itertools import compress, starmap
>>> from operator import gt
Вземете нов списък с booleans, където True
означава елемент в listA
е по-голяма от съответната позиция в listB
.
>>> bools = list(starmap(gt, zip(listA, listB)))
>>> bools
[False, True, False, False, True, False, True, False, False, True]
Сега филтрираме listA
и listD
базиран на bools
използвайки compress
.
>>> list(compress(listA, bools))
[232, 237, 245, 230]
>>> list(compress(listD, bools))
[2, 5, 7, 10]
1 за отговор № 2
Тук няма да използвам разбирането на списъка, а вие строите две списъци, а не един, и това е просто по-лесно с редовен 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)
1 за отговор № 3
Получете резултата от разбирането на списъка:
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]