quarta-feira, 30 de dezembro de 2009

Duplos... só no cinema!

Consideremos o problema de remover os elementos duplicados de uma sequência. Uma solução trivial será:

def remove_duplos_1(seq):
"""Retira elementos duplicados da sequência."""
aux = []
for i,elem in enumerate(seq):
if elem not in seq[i+1:]:
aux.append(elem)
return aux

ou ainda:

def remove_duplos_2(seq):
"""Retira duplicados da sequência."""
return [elem for i,elem in enumerate(seq) if elem not in seq[i+1:]]

Nestes dois casos a ideia é óbvia: pegar num elemento e ver se há mais à sua frente.

Tal como estão, estas soluções funcionam bem para listas. E se for outro tipo de sequências? Cadeias de caracteres, por exemplo:

def remove_duplos_3(seq):
"""Retira elementos duplicados da sequência."""
aux = ''
for i,elem in enumerate(seq):
if elem not in seq[i+1:]:
aux = aux + elem
return aux

Mas se eu souber que existe um tipo de dados set, que implementa conjuntos em Python posso fazer melhor. Por exemplo, no caso das listas:

def remove_duplos_4(seq):
return list(set(seq))


Os conjuntos são colecções não ordenadas, mutáveis e heterogéneas de (referências para) objectos. Existem vários métodos associados com os objectos do tipo set, por exemplo union, intesection e difference. Para saber mais é só consultar o manual de Python.

Claro que agora é fácil encontrar uma solução que dê para diferentes tipos de objectos:

def remove_duplos_5(seq):
aux = set(seq)
if isinstance(seq,str):
return ''.join(aux)
elif isinstance(seq,list):
return list(aux)
elif isinstance(seq,tuple):
return tuple(aux)
else:
print 'TypeError'
return seq

E pronto. Acabaram-se os duplos!

Sem comentários:

Enviar um comentário