Сравните два списка A, B в Python, найдите все элементы в A, соответствующие одному и тому же числу в B
Я хочу сравнить два списка Python: "A" и "B" таким образом, что я могу найти все элементы в A, которые соответствуют одному и тому же числу в B. Я хочу сделать это для каждого номера в B. Например, если
A = [5, 7, 9, 12, 8, 16, 25]
B = [2, 1, 3, 2, 3, 1, 4]
Я хотел бы получить
[7,16] corresponding to the number 1 of listB
[5, 12] corresponding to the number 2 of listB
[9, 8] corresponding to the number 3 of listB
[25] corresponding to the number 4 of listB
A и B всегда будут иметь одинаковую длину.
Ответы
Ответ 1
Вы можете использовать zip
для создания кортежей, которые состоят из одного элемента из обоих списков, затем сортируют их и, наконец, группируют их по значению от B
:
>>> from itertools import groupby
>>> A = [5, 7, 9, 12, 8, 16, 25]
>>> B = [2, 1, 3, 2, 3, 1, 4]
>>> for k, g in groupby(sorted(zip(B,A)), key=lambda x: x[0]):
... print('{} corresponds to {}'.format([x[1] for x in g], k))
...
[7, 16] corresponds to 1
[5, 12] corresponds to 2
[8, 9] corresponds to 3
[25] corresponds to 4
В выше zip(B, A)
возвращается итерабельность кортежей, где каждый кортеж имеет элемент из B
и A
:
>>> list(zip(B,A))
[(2, 5), (1, 7), (3, 9), (2, 12), (3, 8), (1, 16), (4, 25)]
Затем результат сортировки сортируется так, что все кортежи с одинаковым значением из B
находятся рядом друг с другом:
>>> sorted(zip(B,A))
[(1, 7), (1, 16), (2, 5), (2, 12), (3, 8), (3, 9), (4, 25)]
Результат сортировки передается groupby
, который группирует кортежи на основе значения, возвращаемого ключевой функцией, в этом случае первый элемент в кортеже. Результат повторяется с (key, group)
кортежами, где группа итерабельна для элементов:
>>> [(k, list(g)) for k, g in groupby(sorted(zip(B,A)), key=lambda x: x[0])]
[(1, [(1, 7), (1, 16)]), (2, [(2, 5), (2, 12)]), (3, [(3, 8), (3, 9)]), (4, [(4, 25)])]
Ответ 2
Попробуйте этот подход.
unique = set(B) # Creates a set of unique entries in B
for u in unique:
# Find indices of unique entry u
indices = [i for i, x in enumerate(B) if x == u]
# Pull out these indices in A
corrEntry = [A[i] for i in indices]
# Do something with the data, in this case print what OP wants
print('{} corresponds to the number {} of list B'.format(corrEntry , B[indices[0]]))
Он находит уникальные записи в B с помощью функции set
.
Затем мы прокручиваем эти уникальные записи. Первое понимание списка (для indices
) находит индексы записей в B, которые соответствуют этой уникальной записи. Второй сохраняет значение в этих индексов.
Ответ 3
Я думаю, вы можете использовать этот код:
A = [5, 7, 9, 12, 8, 16, 25]
B = [2, 1, 3, 2, 3, 1, 4]
d = {}
for a, b in zip(A, B):
d.setdefault(b, [])
d[b].append(a)
for k, v in sorted(d.items()):
print('{} corresponds {}'.format(v, k))
Каждая клавиша словаря будет элементом B
, и связанное с ней значение будет именно таким списком.
Ответ 4
Альтернатива с использованием collections.defaultdict
:
import collections as ct
dd = ct.defaultdict(list)
for a, b in zip(A, B):
dd[b].append(a)
dd
# defaultdict(list, {1: [7, 16], 2: [5, 12], 3: [9, 8], 4: [25]})
Пример результатов печати:
for k, v in sorted(dd.items()):
print("{} corresponding to the number {} of listB".format(v, k))
# [7, 16] corresponding to the number 1 of listB
# [5, 12] corresponding to the number 2 of listB
# [9, 8] corresponding to the number 3 of listB
# [25] corresponding to the number 4 of listB
Ответ 5
A = [5, 7, 9, 12, 8, 16, 25]
B = [2, 1, 3, 2, 3, 1, 4]
Создайте определенную функцию, которая принимает два списка (A
, B
) и число (n
) в качестве аргументов. Выберите все элементы в A
, которые имеют ту же позицию списка, что и элементы в B
, эквивалентные n
. zip используется для сопряжения элементов из A
и B
с одинаковой позицией списка. Эта функция использует представление списка для выбора элементов из A
.
>>> def f(A, B, n):
return [a for a, b in zip(A,B) if b == n]
>>> f(A, B, 2)
[5, 12]
>>>
Функция может быть записана без понимания списка:
def g(A, B, n):
result = []
for a, b in zip(A, B):
if b == n:
result.append(a)
return result
Используя fuctools.partial, аргументы списка могут быть исправлены:
import functools
f_AB = functools.partial(f, A, B)
Затем его можно использовать следующим образом:
>>> f_AB(3)
[9, 8]
>>> numbers = [3, 4, 2]
>>> for n in numbers:
print (n, f_AB(n))
(3, [9, 8])
(4, [25])
(2, [5, 12])
>>>