How to select from two lists with two matching object atributes?

Viewed 90

I have two lists of objects and I need to select the items that have the same attribute cpf and value:

This is my object class:

class Clientes:

def __init__(self):
    self.nome = ""
    self.cpf = ""
    self.valor = ""
    self.proposta = ""

And this my main code:

from objetos import Clientes


 ArquivoA = {'Cliente1': ['Antonio', '123', '150', 'a'],
           'Cliente2': ['Betina', '456', '200', 'b'],
           'Cliente3': ['Dagmar', '789', '300', 'c'],
           'Cliente4': ['Richard', '001', '400', 'd'],
           'Cliente5': ['Maria', '435', '80', 'e']}


ArquivoB = {'Cliente1': ['Antonio', '123', '150'],
            'Cliente2': ['Betina', '456', '200'],
            'Cliente3': ['Dagmar', '789', '250'],
            'Cliente4': ['Richard', '001', '450'],
            'Cliente5': ['Jose', '987', '500']}

listaA= []
listaB = []

for item in ArquivoA:
    c = Clientes()
    c.nome = ArquivoA[item][0]
    c.CPF = ArquivoA[item][1]
    c.valor = ArquivoA[item][2]
    c.proposta = ArquivoA[item][3]
    listaA.append(c)

print(listaA)

for item in ArquivoB:
    b = Clientes()
    b.nome = ArquivoB[item][0]
    b.CPF = ArquivoB[item][1]
    b.valor = ArquivoB[item][2]
    listaB.append(c)

print(listaB)

I want to create a new list where c.CPF == b.CPF and c.value == b.value. I don't want to use double loop for this, because my real list is so big.

1 Answers

Build dictionaries by your attributes of interest using dict comprehensions. Find common keys using set intersections. Now go and grab the values stored in the lookup dictionaries.

ArquivoA = {'Cliente1': ['Antonio', '123', '150', 'a'],
           'Cliente2': ['Betina', '456', '200', 'b'],
           'Cliente3': ['Dagmar', '789', '300', 'c'],
           'Cliente4': ['Richard', '001', '400', 'd'],
           'Cliente5': ['Maria', '435', '80', 'e']}


ArquivoB = {'Cliente1': ['Antonio', '123', '150'],
            'Cliente2': ['Betina', '456', '200'],
            'Cliente3': ['Dagmar', '789', '250'],
            'Cliente4': ['Richard', '001', '450'],
            'Cliente5': ['Jose', '987', '500']}

class Clientes:
    def __init__(self, nome, CPF, valor, proposta=None):
        self.nome = nome
        self.CPF = CPF
        self.valor = valor
        self.proposta = proposta

    def __repr__(self) -> str:
        return f"{self.__dict__}"

list_a =  [Clientes(v[0], v[1], v[2],v[3]) for v in ArquivoA.values()]
list_b =  [Clientes(v[0], v[1], v[2]) for v in ArquivoB.values()]

#build a lookup dictionary by CPF, valor
di_a = {(c.CPF, c.valor) : c for c in list_a}
di_b = {(c.CPF, c.valor) : c for c in list_b}

#use sets to find common keys
set_a = set(di_a.keys())
set_b = set(di_b.keys())
common = set_a & set_b 

#compare or do something else with the matching instances
for key in common:
    va = di_a[key]
    vb = di_b[key]

    print(f"\n\n{key}:\n  {va=}\n  {vb=}" )    


output:



('123', '150'):
  va={'nome': 'Antonio', 'CPF': '123', 'valor': '150', 'proposta': 'a'}
  vb={'nome': 'Antonio', 'CPF': '123', 'valor': '150', 'proposta': None}


('456', '200'):
  va={'nome': 'Betina', 'CPF': '456', 'valor': '200', 'proposta': 'b'}
  vb={'nome': 'Betina', 'CPF': '456', 'valor': '200', 'proposta': None}

Related