Λίγο πολύ πρέπει να γράψω ένα πρόγραμμα για να ελέγξω αν μια λίστα έχει διπλά και αν έχει, τα αφαιρεί και επιστρέφει μια νέα λίστα με τα στοιχεία που δεν έχουν διπλασιαστεί/αφαιρέσει. Αυτό είναι αυτό που έχω, αλλά για να είμαι ειλικρινής δεν ξέρω τι να κάνω.
def remove_duplicates():
t = ['a', 'b', 'c', 'd']
t2 = ['a', 'c', 'd']
for t in t2:
t.append(t.remove())
return t
Η συνήθης προσέγγιση για να αποκτήσετε μια μοναδική συλλογή στοιχείων είναι η χρήση ενός set
. Τα σύνολα είναι άτακτες συλλογές διαφορετικών αντικειμένων. Για να δημιουργήσετε ένα σύνολο από οποιοδήποτε επαναληπτικό, μπορείτε απλά να το περάσετε στην ενσωματωμένη συνάρτηση set()
. Αν αργότερα χρειαστείτε ξανά μια πραγματική λίστα, μπορείτε ομοίως να περάσετε το σύνολο στη συνάρτηση list()
.
Το ακόλουθο παράδειγμα θα πρέπει να καλύπτει ό,τι προσπαθείτε να κάνετε:
>>> t = [1, 2, 3, 1, 2, 5, 6, 7, 8]
>>> t
[1, 2, 3, 1, 2, 5, 6, 7, 8]
>>> list(set(t))
[1, 2, 3, 5, 6, 7, 8]
>>> s = [1, 2, 3]
>>> list(set(t) - set(s))
[8, 5, 6, 7]
Όπως μπορείτε να δείτε από το αποτέλεσμα του παραδείγματος, η αρχική σειρά δεν διατηρείται. Όπως αναφέρθηκε παραπάνω, τα ίδια τα σύνολα είναι μη ταξινομημένες συλλογές, οπότε η σειρά χάνεται. Κατά τη μετατροπή ενός συνόλου πίσω σε λίστα, δημιουργείται μια αυθαίρετη σειρά.
Αν η τάξη είναι σημαντική για εσάς, τότε θα πρέπει να χρησιμοποιήσετε έναν διαφορετικό μηχανισμό. Μια πολύ συνηθισμένη λύση για αυτό είναι να βασιστείτε στο OrderedDict
για να διατηρήσετε τη σειρά των κλειδιών κατά την εισαγωγή:
>>> from collections import OrderedDict
>>> list(OrderedDict.fromkeys(t))
[1, 2, 3, 5, 6, 7, 8]
Ξεκινώντας από την Python 3.7, το ενσωματωμένο λεξικό είναι εγγυημένο ότι διατηρεί επίσης τη σειρά εισαγωγής, οπότε μπορείτε επίσης να το χρησιμοποιήσετε απευθείας αν είστε σε Python 3.7 ή νεότερη έκδοση (ή CPython 3.6):
>>> list(dict.fromkeys(t))
[1, 2, 3, 5, 6, 7, 8]
Σημειώστε ότι αυτό έχει την επιβάρυνση της δημιουργίας ενός λεξικού πρώτα, και στη συνέχεια της δημιουργίας μιας λίστας από αυτό. Αν δεν χρειάζεται στην πραγματικότητα να διατηρήσετε τη σειρά, είναι καλύτερα να χρησιμοποιήσετε ένα σύνολο. Ελέγξτε την αυτή την ερώτηση για περισσότερες λεπτομέρειες και εναλλακτικούς τρόπους διατήρησης της σειράς κατά την αφαίρεση διπλοτύπων.
Τέλος, σημειώστε ότι τόσο το set
όσο και οι λύσεις OrderedDict
/dict
απαιτούν τα στοιχεία σας να είναι hashable. Αυτό συνήθως σημαίνει ότι πρέπει να είναι αμετάβλητα. Αν πρέπει να ασχοληθείτε με αντικείμενα που δεν είναι hashable (π.χ. αντικείμενα λίστας), τότε θα πρέπει να χρησιμοποιήσετε μια αργή προσέγγιση στην οποία θα πρέπει ουσιαστικά να συγκρίνετε κάθε αντικείμενο με κάθε άλλο αντικείμενο σε έναν εμφωλευμένο βρόχο.
Είναι μια απλή αράδα: list(set(source_list))
θα κάνει το κόλπο.
Ένα set
είναι κάτι που δεν είναι δυνατόν να έχει αντίγραφα.
Ενημέρωση: μια προσέγγιση με διατήρηση της σειράς είναι δύο γραμμές:
from collections import OrderedDict
OrderedDict((x, True) for x in source_list).keys()
Εδώ χρησιμοποιούμε το γεγονός ότι το OrderedDict
θυμάται τη σειρά εισαγωγής των κλειδιών και δεν την αλλάζει όταν ενημερώνεται μια τιμή σε ένα συγκεκριμένο κλειδί. Εισάγουμε το True
ως τιμές, αλλά θα μπορούσαμε να εισάγουμε οτιδήποτε, απλά οι τιμές δεν χρησιμοποιούνται. (Το set
λειτουργεί επίσης σαν ένα dict
με αγνοημένες τιμές).
Αν δεν σας ενδιαφέρει η σειρά, κάντε απλά αυτό:
def remove_duplicates(l):
return list(set(l))
Ένα set
είναι εγγυημένο ότι δεν θα έχει διπλότυπα.