Digamos que eu tenho dois set()
s:
a = {('1', '2', '3', 'a'), ('1', '2', '4', 'a'), ('1', '2', '5', 'b')}
b = {('1', '2', '3', 'b'), ('1', '2', '4', 'b'), ('1', '2', '6', 'b')}
Agora, o que eu quero fazer é encontrar a diferença definida, b \ a
mas ignorando o último elemento de cada tupla. Então é como fazer algo assim:
a = {('1', '2', '3'), ('1', '2', '4'), ('1', '2', '5')}
b = {('1', '2', '3'), ('1', '2', '4'), ('1', '2', '6')}
In[1]: b - a
Out[1]: {('1', '2', '6')}
Saída esperada:
b \ a = {('1', '2', '6', 'b')}
Existe alguma maneira óbvia / pitônica de conseguir isso sem ter que iterar manualmente sobre cada conjunto e comparar com cada um tuple[:3]
?
python
python-2.7
set
Grajdeanu Alex.
fonte
fonte
set
e substitua a operação de diferença. Não tenho uma solução pronta para uso e duvido que exista.aa = { t[:3] for t in a }
tuple
e substitua o operador de diferençaRespostas:
Veja como você pode escrever sua própria classe para substituir o comportamento de hash normal de uma tupla:
com saída
Para modificar a maneira como os conjuntos de tuplas se comportam, precisamos modificar a maneira como as tuplas são hash.
A partir daqui ,
Portanto, para fazer com que o hash ignore o último elemento, precisamos sobrecarregar os métodos dunder
__eq__
e__hash__
adequadamente. Isso não acaba sendo tão difícil, porque tudo o que precisamos fazer é cortar o último elemento e, em seguida, delegar aos métodos apropriados de um método normal.tuple
.Leitura adicional:
fonte
:)
. Realmente, é apenas a combinação de bits de sobrecarga do operador e como o hash funciona no Python.Aqui está uma abordagem que define
a
eb
com listas em vez de conjuntos, pois me parece que a solução mais direta implica a indexaçãob
:fonte
Conjuntos funcionam bem. São seus dados que não funcionam corretamente. Se eles parecerem diferentes, mas na verdade forem iguais, defina um tipo de dados que se comporte como você deseja. Em seguida, o conjunto funciona muito bem por conta própria.
fonte
__repr__
e__hash__
em termos de tuplas, mas não__eq__
. Também não seria mais curto usar tuplas aqui? Na verdade, você pode usar o fatiamento aqui e__hash__
para diminuir ainda mais o código.