Ακολουθεί μια κατανομή για το πώς να χρησιμοποιήσετε αποτελεσματικά το `itertools.permutations ', μαζί με το γιατί το` np.random.permution` δεν είναι κατάλληλη για τη δημιουργία όλων των παραλλαγών:
1. Χρησιμοποιώντας `itertools.permutations` (η συνιστώμενη προσέγγιση)
`` `Python
Εισαγωγή itertools
def all_permutations (input_list):
"" "
Δημιουργεί όλες τις πιθανές μεταβολές μιας λίστας.
Args:
Input_List:Η λίστα για την οποία θα δημιουργήσει μεταβολές.
Επιστρέφει:
Μια γεννήτρια που αποδίδει πλειάδες, όπου κάθε πλειάδα είναι μια μετάθεση.
"" "
επιστρέψτε itertools.permutations (input_list)
my_list =[1, 2, 3]
μεταβολές =all_permutations (my_list)
για perm στις μεταβολές:
Εκτύπωση (perm) # Εκτυπώνει κάθε μετασχηματισμό ως πλειάδα.
my_list =[1, 2, 3]
μεταβολές =all_permutations (my_list)
για perm στις μεταβολές:
Εκτύπωση (λίστα (perm)) # Εκτυπώνει κάθε μετάθεση ως λίστα
my_list =[1, 2, 3]
Permutations =List (all_permutations (my_list)) # μετατρέψτε τη γεννήτρια σε μια λίστα
list_of_lists =[list (perm) για perm in permutations] # μετατρέψτε την πλειάδα στη λίστα
εκτύπωση (List_of_Lists)
`` `
Επεξήγηση:
* `itertools.permutations (input_list)`: Αυτός είναι ο πυρήνας της λύσης. Επιστρέφει έναν * iterator * (συγκεκριμένα, ένα αντικείμενο `permutations '). Ένας iterator είναι αποδοτικός από τη μνήμη επειδή παράγει παραλλαγές κατόπιν αιτήματος, μία κάθε φορά, αντί να τις δημιουργεί όλα ταυτόχρονα στη μνήμη. Αυτό είναι ζωτικής σημασίας για μεγαλύτερες λίστες όπου ο αριθμός των μεταβολών μπορεί να γίνει εξαιρετικά μεγάλος (το n! Μεγαλώνει πολύ γρήγορα).
* γεννήτρια: Η χρήση μιας γεννήτριας (ο iterator) είναι σημαντική για την αποτελεσματικότητα. Εάν μετατρέψετε τη γεννήτρια σε μια λίστα εκ των προτέρων (π.χ. λίστα (itertools.permutations (input_list)) `), θα δημιουργήσετε * όλες τις * μεταβολές αμέσως, γεγονός που μπορεί να οδηγήσει σε προβλήματα μνήμης για μεγαλύτερες λίστες εισροών. Επεξεργαστείτε τις μεταβολές μία προς μία χρησιμοποιώντας ένα "για" βρόχο ".
* `Tuple` output: Το `itertools.permutations 'επιστρέφει κάθε μεταστροφή ως` tuple'. Εάν χρειάζεστε την έξοδο ως λίστα ", μπορείτε να μετατρέψετε την πλειάδα χρησιμοποιώντας τη λίστα (perm)`.
* Αποδοτικότητα: Το `itertools.permutations 'εφαρμόζεται στο C και είναι εξαιρετικά βελτιστοποιημένο για αυτό το έργο. Είναι ο πιο αποτελεσματικός τρόπος για τη δημιουργία μεταβολών στην Python.
2. Γιατί το «np.random.permationation» είναι ακατάλληλο
Το «np.random.permationation» έχει σχεδιαστεί για τη δημιουργία * τυχαίων * παραλλαγών, όχι όλων αυτών. Εδώ γιατί δεν θα λειτουργήσει σωστά για τον προβλεπόμενο σκοπό:
* τυχαία: Δημιουργεί μια ενιαία τυχαία μετάθεση κάθε φορά που το ονομάζετε.
* Καμία εγγύηση όλων των μεταβολών: Για να πάρετε * όλες τις * παραλλαγές με `np.random.permationation`, θα χρειαστεί να το ονομάσετε επανειλημμένα μέχρι να δείτε όλα τα n! δυνατότητες. Δεν υπάρχει τρόπος να γνωρίζετε πότε έχετε εξαντλήσει όλες τις παραλλαγές χωρίς να παρακολουθείτε αυτά που έχετε ήδη δει, κάτι που γίνεται εξαιρετικά περίπλοκο και αναποτελεσματικό. Δεν υπάρχει καμία εγγύηση ότι θα δημιουργήσετε ποτέ κάθε πιθανή μετάθεση με αυτόν τον τρόπο.
* Αναποτελεσματική επανάληψη: Θα δημιουργούσατε πολλές διπλές παραλλαγές πριν τελικά (ίσως ποτέ) να βλέπετε όλα αυτά.
Λανθασμένη (και αναποτελεσματική) προσπάθεια να χρησιμοποιήσετε το `np.random.permution` (μόνο επεξηγηματικούς σκοπούς - μην χρησιμοποιείτε):
`` `Python
Εισαγωγή Numpy ως NP
def enterply_permutations_with_numpy (input_list):
"" "
Μην το χρησιμοποιείτε! Είναι μια λανθασμένη και αναποτελεσματική προσπάθεια
να δημιουργηθεί όλες οι μεταβολές χρησιμοποιώντας το np.random.permation.
"" "
seen_permutations =set ()
all_perms =[]
n =len (input_list)
factorial_n =np.math.factorial (n) # Αυτό μπορεί να ξεχειλίσει!
ενώ το len (seen_permutations)
Εάν δεν είναι perm σε deed_permutations:
seen_permutations.add (perm)
all_perms.append (λίστα (perm))
επιστροφή all_perms
my_list =[1, 2, 3]
`` `
Προβλήματα με την απόπειρα Numpy:
* Θέματα μνήμης: Το σύνολο `seen_permutations 'θα αναπτυχθεί γρήγορα σε ένα τεράστιο μέγεθος, ενδεχομένως να υπερβαίνει τη διαθέσιμη μνήμη, ειδικά για ελαφρώς μεγαλύτερες λίστες.
* Αποδοτικότητα: Η συνθήκη βρόχου `len (seen_permutations)
* Μετατροπή πλειάδας: Η μετατροπή των θηλυκών συστοιχιών σε πλειάδες και πίσω στους καταλόγους είναι ένα γενικό εξόδους που αποφεύγει το `itertools '.
Συνοπτικά:
Για τη δημιουργία όλων των πιθανών μεταβολών μιας λίστας στο Python, χρησιμοποιείτε πάντα το `itertools.permutations ' . Είναι ο σωστός, πιο αποτελεσματικός και πυθονικός τρόπος για την επίλυση αυτού του προβλήματος. Αποφύγετε τη χρήση του `np.random.permution 'για το σκοπό αυτό, καθώς έχει σχεδιαστεί για διαφορετική εργασία και θα οδηγήσει σε εσφαλμένο και αναποτελεσματικό κώδικα.
Μην χρησιμοποιείτε αυτό το παράδειγμα! Είναι μόνο για την επίδειξη του γιατί είναι λανθασμένη.
permutations =enterper_all_permutations_with_numpy (my_list) # ενδεχομένως κρέμεται ή χρησιμοποιεί υπερβολική μνήμη.
εκτύπωση (μεταβολές)
Πνευματικά δικαιώματα © Γνώση Υπολογιστών Όλα τα δικαιώματα κατοχυρωμένα