Как убрать соответствующее значение в трех списках, которые дублируются? - PullRequest
0 голосов
/ 10 января 2019

У меня есть три списка, которые похожи на:

a = [0, 0, 0, 1, 1, 2, 2, 2, 3, 3]
b = [1, 2, 3, 0, 9, 0, 3, 5, 0, 1]
c = [0.1, 0.4, 0.5, 0.7, 0.8, 0.44, 0.6, 0.9, 0.3, 0.77]

Если значение соответствует b, первое значение в a и b равно 0,1, что соответствует четвертому значению в a и b 1,0, и я хочу удалить его в a,b,c чтобы получить список:

aa:[0,0,0,1,2,2,3]
bb:[1,2,3,9,3,5,1]
cc:[0.1,0.4,0.5,0.8,0.6,0.9,0.77] 

И я попытался использовать удаление:

for i,u in enumerate(a):
   if a[i] == b[i] and b[i] == a[i]:
      a.remove(a[i])
      b.remove(b[i])
      c.remove(c[i])

И это не сработало. Кто-нибудь может дать мне знать, как я могу это сделать?

Ответы [ 4 ]

0 голосов
/ 10 января 2019

Потому что никто еще не упомянул frozenset:

In [1]: a = [0, 0, 0, 1, 1, 2, 2, 2, 3, 3]
   ...: b = [1, 2, 3, 0, 9, 0, 3, 5, 0, 1]
   ...: c = [0.1, 0.4, 0.5, 0.7, 0.8, 0.44, 0.6, 0.9, 0.3, 0.77]

In [2]: seen = set()
   ...: to_del = []
   ...: for i, n in enumerate(a):
   ...:     pair = frozenset((n, b[i]))
   ...:     if pair in seen:
   ...:         to_del.append(i)
   ...:     else:
   ...:         seen.add(pair)
   ...:
   ...: for i in reversed(to_del):
   ...:     del a[i]
   ...:     del b[i]
   ...:     del c[i]
   ...:

In [3]: a
Out[3]: [0, 0, 0, 1, 2, 2, 3]

In [4]: b
Out[4]: [1, 2, 3, 9, 3, 5, 1]

In [5]: c
Out[6]: [0.1, 0.4, 0.5, 0.8, 0.6, 0.9, 0.77]

Или, если вы хотите создать новую копию a, b и c и оставить исходные списки без изменений:

In [2]: aa, bb, cc = [], [], []
   ...: seen = set()
   ...: for i, n in enumerate(a):
   ...:     pair = frozenset((n, b[i]))
   ...:     if pair not in seen:
   ...:         seen.add(pair)
   ...:         aa.append(n)
   ...:         bb.append(b[i])
   ...:         cc.append(c[i])
   ...:

In [3]: aa
Out[3]: [0, 0, 0, 1, 2, 2, 3]

In [4]: bb
Out[4]: [1, 2, 3, 9, 3, 5, 1]

In [5]: cc
Out[5]: [0.1, 0.4, 0.5, 0.8, 0.6, 0.9, 0.77]
0 голосов
/ 10 января 2019

Если я правильно понимаю ваш вопрос, код, приведенный ниже, выполнит эту работу.

removed_indices = []
for i in range(len(a)):
    for j in range(i+1, len(a)):
        if j in removed_indices:
            continue
        if a[i] == b[j] and b[i] == a[j]:
            removed_indices.append(j)
for i in reversed(removed_indices):
    a.pop(i)
    b.pop(i)
    c.pop(i)

Сначала он находит позиции повторяющихся элементов (j во втором цикле for) и, если он еще не был удален, добавит его в список (remove_indices). Наконец, код удаляет элементы в обратном направлении (для поддержания порядка позиций).

0 голосов
/ 10 января 2019

Решение, вы создаете новый список NewA, NewB, NewC, копируя каждый кортеж. Но перед копированием вы проверяете, существует ли кортеж.

NewA = []
NewB = []
NewC = []

for i,u in enumerate(a):
    found=0
    for j,v in enumerate(NewA):
        if a[i] == NewB[j] and b[i] == NewA[j] :
        found=1
    if found == 0 :
        NewA.append(a[i])
        NewB.append(b[i])
        NewC.append(c[i])
0 голосов
/ 10 января 2019

Вы можете перебирать свои списки и создавать список селекторов, например ::

seen = set()
selectors = []
for x, y in zip(a, b):
    if (x, y) in seen:
        selectors.append(0)
        continue
    seen.add((y, x))
    selectors.append(1)

Примечание: если порядок не имеет значения (то есть исключите (1, 0) и (0, 1)), тогда вы можете использовать frozenset(x, y) вместо кортежей в наборе seen.

Теперь вы можете использовать эти selectors с itertools.compress(), например ::

In []:
import itertools as it
list(it.compress(c, selectors))

Out[]:
[0.1, 0.4, 0.5, 0.8, 0.6, 0.9, 0.77]

Чтобы получить окончательные переменные:

aa = list(it.compress(a, selectors))  # [0, 0, 0, 1, 2, 2, 3]
bb = list(it.compress(b, selectors))  # [1, 2, 3, 9, 3, 5, 1]
cc = list(it.compress(c, selectors))  # [0.1, 0.4, 0.5, 0.8, 0.6, 0.9, 0.77]

Или более кратко:

aa, bb, cc = [list(it.compress(lst, selectors)) for lst in (a, b, c)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...