Intersection between lists without repeating elements

Asked

Viewed 172 times

2

I have to make a code that reads two strings of numbers, convert them into int, store in a list and print list A (first string numbers), list B (second string numbers) and list C (common numbers in both lists). I already made the code but when I print the C list it repeats the numbers instead of just showing them once.
Example:

lista A = [1 2 1 1 1]  
lista B = [1 3 4 5 6]    

But on list C, instead of just printing [1], she prints [1, 1, 1, 1].

Note: I know there are functions in Python that make the intersection, but the purpose of the exercise is to do without using them.

A = []
B = []
C = []
C2 = []
A = input('A: ')
B = input('B: ')
A = A.split()
B = B.split()
for x in range(0, len(A), 1):
    A[x] = int(A[x])
for x in range(0, len(B), 1):
    B[x] = int(B[x])
for y in A:
    for x in B:
        if x == y:
            C = C + [x]
[C2.append(i) for i in C]
print("A =", A)
print("B =", B)
print("C =", C2)

2 answers

2


An option is, for each element of A, check if it exists in B and does not yet exist in C:

A = list(map(int, input('A: ').split()))
B = list(map(int, input('B: ').split()))
C = []
for x in A: # para cada elemento de A
    if x in B and x not in C: # se também está em B e ainda não está em C
        C.append(x)

Note also that you can simplify the reading of lists (do the split and turn values into int at once). And also does not need the auxiliary list C2.


It has been said that "Python functions that intersect" cannot be used, but only to log the solution with set:

C = list(set(A) & set(B))

Remembering that a set does not guarantee order between the elements, so C will not necessarily have the elements in the same order they appear in the original lists.


It is worth remembering that the solution with set is more efficient, since the first option has to sweep the lists B and C several times to check if the element exists. Running a quick test with module timeit:

from random import choices
# gerar listas aleatórias com 1000 números entre 0 e 99 (para ter elementos repetidos)
r = range(100)
A = choices(r, k=1000)
B = choices(r, k=1000)

from timeit import timeit
# executar cada teste 100 vezes
params = { 'number': 100, 'globals': globals() }
opcao1 = """C = []
for x in A:
    if x in B and x not in C:
        C.append(x)"""
opcao2 = "C = list(set(A) & set(B))"

# imprime o tempo em segundos
print(timeit(opcao1, **params))
print(timeit(opcao2, **params))

The times can vary from one machine to another and depends on several factors (if there were other processes running, if there are many numbers repeated in the lists, etc), but in general, on my machine I got times around 0.2 seconds with the for and 0.004 seconds with set (that is, the solution with set was about 50 times faster).

1

Another interesting way to resolve this issue is the following:

from itertools import chain

A = [int(x) for x in input('Valores de "A": ').split()]
B = [int(x) for x in input('Valores de "B": ').split()]
C = list()
for item in chain(A, B):
    if (item in A) and (item in B) and (item not in C):
        C.append(item)
C.sort()
print(C)

Note that when we execute this code we receive first message: Valores de "A": . Right now we must type all the elements of the list A, in same line, separated for a single space and press enter. Then we will receive the second message: Valores de "B": . At this point we must enter all the elements of the list B just like we typed in the list A and press enter.

Observation 1:

Objects "A" and "B" are listas. These were assembled from List Comprehension.

Observation 2:

When using the method chain library itertools, enabled code to work with lists of different sizes.

After we have entered all the values of both lists, the block for, with the help of the method chain library itertools, will scroll through both lists simultaneously. At each iteration, it will be checked whether the temporary variable - item - is contained in both lists - A and B - and if it’s not on the list C. If yes, the value of item will be stored in the list C. The list is then ordered in increasing order and then displayed.

Observation 3:

As already mentioned in the other answer, this whole procedure could be performed more efficiently if, by chance, we use the set. The resolution with the function set would be:

A = [int(x) for x in input('Valores de "A": ').split()]
B = [int(x) for x in input('Valores de "B": ').split()]

print(sorted(list(set(A) & set(B))))

Browser other questions tagged

You are not signed in. Login or sign up in order to post.