Himpunan unik di Python

Sebelum ini, saya sempat menulis tentang cara membuat fungsi pembanding sendiri untuk keperluan pembuatan himpunan unik. Singkatnya, di bahasa Java, Scala, dan mungkin bahasa lain yang jalan di atas JVM, kita perlu mengimplementasikan ulang method hashCode dan equals. Setelah menulis itu, saya sempat berpikir bagaimana cara melakukannya di Python?

Yang ingin saya lakukan adalah jika saya memiliki beberapa objek penampung nilai, saya ingin membuat mereka unik (katakanlah dengan memasukkannya ke dalam set). Jadi jika ada lebih dari satu objek yang bernilai sama, hanya satu di antara mereka saja yang diambil. Sisanya bisa dibuang karena saya tidak memerlukannya.

Katakanlah saya memiliki kelas seperti berikut.

class M(object):
    def __init__(self, posisi, asam_amino):
        self.posisi = posisi
        self.asam_amino = asam_amino

    def __repr__(self):
        return "%s%s" % (self.posisi, self.asam_amino)

Lalu saya membuat beberapa objek dari kelas tersebut.

mutasi = [ M(1, "a"), M(2, "b"), M(1, "c"), M(3, "b"), M(1, "a") ]

Mari kita coba panggil fungsi set

>>> print mutasi
[1a, 2b, 1c, 3b, 1a]
>>> print set(mutasi)
set([3b, 1c, 1a, 1a, 2b])

Seperti yang sudah diduga, fungsi set belum berhasil menghapus nilai ganda.

Setelah ngubek2 sana sini, ternyata di Python kita juga harus mengimplementasikan dua buah method yang sama (versi Python tentunya)! Kedua method tersebut adalah __eq__ dan __hash__. Kedua method ini dapat diimplementasikan ulang seperti berikut.

    def __eq__(self, o):
        if not isinstance(o, M):
            return False
        return self.posisi == o.posisi \
               and self.asam_amino == o.asam_amino

    def __hash__(self):
        return hash((self.posisi, self.asam_amino))

Mari kita coba lagi sekarang.

>>> mutasi = [ M(1, "a"), M(2, "b"), M(1, "c"), M(3, "b"), M(1, "a") ]
>>> print mutasi
[1a, 2b, 1c, 3b, 1a]
>>> print set(mutasi)
set([1c, 1a, 2b, 3b])

Klopt!

Kode lengkap dapat dilihat di https://gist.github.com/fajran/5744836

Leave a Reply