2015-05-07 2 views
2

У меня есть два списка (одинакового размера)Получить число вхождений пары значений в одном индексе в двух разных списках

a = [0, 0, 1, 0, 0, 1, 1, 0] 
b = [2, 2, 0, 2, 1, 1, 0, 2] 

Предположим, что мне нужно, чтобы получить количество вхождений значения «2» в списке 'b', когда значение '0' сопоставляется в списке 'a'. например, в двух предыдущих списках, я ожидаю получить 4 (у меня есть значения «0» в «a» и «2» в «b» одновременно в позициях 0,1,3,7)

Один из способов сделать это:

len([x for x,y in zip(a,b) if x==0 and y==2]) 

Но мне было интересно, если есть лучшее решение

+0

Вы имели в виду список, а не массив, правильно? – thefourtheye

ответ

3

Если массивы (возможно, вы имели в виду списки) будут больше, используя itertools.izip бы лучше, потому что zip создаст список кортежей соответствующих элементы от обоих a и b

>>> a = [0, 0, 1, 0, 0, 1, 1, 0] 
>>> b = [2, 2, 0, 2, 1, 1, 0, 2] 
>>> from itertools import izip 
>>> sum(x == 0 and y == 2 for x, y in izip(a, b)) 
4 

Здесь, x == 0 and y == 2 это логическое выражение, так что результат будет либо True или False. В Python True - 1 и False - 0.

>>> False == 0 
True 
>>> True == 1 
True 

и sum функция суммирует все из них и дает результат.

Также обратите внимание, что мы не передаем список sum ([ и ] не существует). Это означает, что мы передаем выражение генератора. sum будет вызывать выражение генератора для получения значения. Таким образом, временный список не создается, как в вашем решении len, но значения извлекаются по требованию. Подробнее о генераторах и выражениях генератора, here

Таким образом, это решение будет очень эффективным и очень полезным в пространстве, если ваши списки будут очень длинными (поскольку это позволяет избежать временного построения списка).

1

Ну, стиль мудрый это кажется очень вещий и понятно, так что для меня это достаточно хорошо.

Вы должны выполнить итерацию так, чтобы я не думал, что вы есть. Единственным улучшением будет использование izip, а не создание фактического списка совпадающих элементов. Что-то по строкам:

from itertools import izip 
sum(1 for x,y in izip(a,b) if x==0 and y==2) 

может работать. В любом случае улучшайте, только если это необходимо по производительности. (Кстати вы забыли запятые между элементами в вашем примере)

0
sum(x == 0 and y == 2 for x, y in zip(a, b)) 
2

Если ваши списки не смехотворно большие, просто использовать list.count:

a = [0, 0, 1, 0, 0, 1, 1, 0] 
b = [2, 2, 0, 2, 1, 1, 0, 2] 
print(zip(a,b).count((0,2))) 

Для Python 3, где почтовый возвращает итератор, вы должны будете использовать список (ZIP (..)) для составления списка. Если вы хотите подсчитать несколько вариантов, коллекции.Счетчик может сделать:

>>> print collections.Counter(zip(a,b)) 
Counter({(0, 2): 4, (1, 0): 2, (0, 1): 1, (1, 1): 1}) 

Кроме того, зная, что в Python истина и ложь имеют числовые значения 1 и 0 (на самом деле, BOOL является подтипом межд), мы можем просто просуммировать генератор:

sum(pair==(0,2) for pair in zip(a,b)) 
Смежные вопросы