2012-03-28 6 views
2

Я хочу сравнить списки этого вида:питона найти различающиеся элементы в списке

A = [0,1,0,1,0,1,0,0,0,1,0,1,0,1,0] 
B = [0,1,0,1,0,0,0,1,0,1,0,1,0,1,0] 

и выяснить, какие элементы отличаются. В этом случае он должен вернуть индекс 5 из A и индекс 7 из B. Все остальные элементы одинаковы. Есть ли функция для этого?

лучший, США

+0

Почему не индекс 5 из B или индекс 7 A? Вы принимаете какой-либо шаблон? –

+0

Нет шаблона.Просто подсчитываю. – user366121

ответ

4
>>> [index for (_, index) in set(zip(A, xrange(len(A)))) - set(zip(B, xrange(len(B))))] 
[5, 7] 

Что на земле это?

  1. Почтовый индекс с увеличивающимися номерами. Итак, создайте список кортежей, где первым значением является элемент в списке, а второй - его индекс.
  2. Создавайте множество из каждого, поэтому их можно сравнить с заданными функциями. Кортежи неизменны, поэтому hashable, поэтому могут храниться в наборе
  3. Возьмите разность множеств между двумя
  4. Подбери индекс различных элементов

РЕДАКТИРОВАНИЕ

Благодаря Комментарий Романа, это проще, но делает то же самое.

>>> [index for (index, _) in set(enumerate(A)) - set(enumerate(B))] 
[5, 7] 

Обратите внимание, что в то время как zip создает список, enumerate производит перечислимого, который сразу же перечисляются для создания списка. Также он производит tupes типа (index, value), а не (value, index), как в приведенном выше ответе.

+2

'zip (A, xrange (len (A)))' is 'enumerate (A)' –

+0

Хорошо, но я пропускаю функцию xrange. В каком модуле он находится? – user366121

+0

xrange находится в стандарте lib – vascop

1

Вы обязательно хотите один вкладыш? Потому что в противном случае есть более простой код:

for i in range(len(A)): 
    if A[i]!=B[i]: 
     print i 
+0

Все в порядке. Thx – user366121

1

Нечто подобное необходимо сделать трюк (непроверенный):

[i for i, v in enumerate(zip(A, B)) if sum(v) == 1] 

Это будет возвращать список номеров элементов, которые имеют различные значения в каждом списке.

Если набор данных отличается в этом вопросе, то вы могли бы использовать это:

[i for i, v in enumerate(zip(A, B)) if v[0] != v[1]] 
+1

Пока это только 1s и 0s! – jamylak

+0

@jamylak: Это означает «так же, как в вопросе! _» :) – Tadeck

+0

, если кто-то не пытается найти разные предметы в двух разных типах списков, nevermind hahaha – jamylak

1

Другой (возможно, более удобным для чтения?) Один вкладыш:

>>> [index for (index,(a,b)) in enumerate(zip(A,B)) if a!=b] 
[5, 7] 

Этот первый застежки-молнии в перечислены вместе:

[(0, 0), (1, 1), (0, 0), (1, 1), (0, 0), (1, 0), (0, 0), (0, 1), (0, 0), 
(1, 1), (0, 0), (1, 1), (0, 0), (1, 1), (0, 0)] 

А затем присоединяет индекс к элементам с enumerate() Функции:

[(0, (0, 0)), (1, (1, 1)), (2, (0, 0)), (3, (1, 1)), (4, (0, 0)), (5, (1, 0)), 
(6, (0, 0)), (7, (0, 1)), (8, (0, 0)), (9, (1, 1)), (10, (0, 0)), (11, (1, 1)), 
(12, (0, 0)), (13, (1, 1)), (14, (0, 0))] 

Затем он использует довольно стандартный list comprehension для сравнения элементов строит список индексов, где элементы не совпадают.

+0

Ваш ответ очень похож на мой. Вы согласны? – Tadeck

+0

Я согласен. Твоя была опубликована, когда я писал мой ... ты хочешь, чтобы я удалил свой ответ? –

+0

Затем вы писали свой ответ в течение 20 минут, пока не отправили его;) Нет, если вы хотите, чтобы он остался, не удаляйте его. Но, пожалуйста, добавьте некоторое значение, чтобы другие не рассматривались как ответ «копировать и вставлять». – Tadeck