Για να δημιουργήσετε μια νέα λίστα από μια λίστα (πίνακα) της οποίας τα στοιχεία είναι συμβολοσειρές, εξάγοντας μόνο τα στοιχεία των συμβολοσειρών που ικανοποιούν ορισμένες συνθήκες, ή εκτελώντας αντικαταστάσεις, μετατροπές κ.λπ., χρησιμοποιήστε την κατανόηση λίστας.
Μετά από μια σύντομη επεξήγηση της κατανόησης λίστας, εξηγούνται τα ακόλουθα περιεχόμενα με δείγμα κώδικα.
- Εξαγωγή με βάση το αν περιλαμβάνεται ή όχι μια συγκεκριμένη συμβολοσειρά (μερική αντιστοίχιση)
- Αντικατάσταση συγκεκριμένης συμβολοσειράς
- Εξαγωγή ξεκινώντας ή μη ξεκινώντας με μια συγκεκριμένη συμβολοσειρά
- Εξαγωγή με κατάληξη ή μη κατάληξη σε μια συγκεκριμένη συμβολοσειρά
- Κρίνεται και εξάγεται κατά περίπτωση
- Μετατροπή κεφαλαίων και πεζών
- Καθορίζει αν χρησιμοποιούνται αλφαβητικοί ή αριθμητικοί χαρακτήρες και τους εξάγει
- Πολλαπλές συνθήκες
- (υπολογιστής) κανονική έκφραση
Σημειώστε ότι οι λίστες μπορούν να αποθηκεύουν διαφορετικούς τύπους δεδομένων και διαφέρουν αυστηρά από τους πίνακες. Αν θέλετε να χειρίζεστε πίνακες σε διαδικασίες που απαιτούν μέγεθος μνήμης και διευθύνσεις μνήμης ή αριθμητική επεξεργασία μεγάλων δεδομένων, χρησιμοποιήστε array (standard library) ή NumPy.
- συμβολισμός συμπερίληψης λίστας
- Περιέχει μια συγκεκριμένη συμβολοσειρά (μερική αντιστοιχία) \ Δεν περιέχει: in
- Αντικατάσταση συγκεκριμένης συμβολοσειράς
- Ξεκινάει με μια συγκεκριμένη συμβολοσειρά \ δεν ξεκινάει: startswith()
- Τελειώνει με μια συγκεκριμένη συμβολοσειρά χαρακτήρων \ δεν τελειώνει: endswith()
- Κρίνεται και εξάγεται κατά περίπτωση
- Μετατροπή κεφαλαίων και πεζών
- Καθορίζει αν χρησιμοποιούνται αλφαβητικοί ή αριθμητικοί χαρακτήρες και τους εξάγει
- Πολλαπλές συνθήκες
- (υπολογιστής) κανονική έκφραση
συμβολισμός συμπερίληψης λίστας
Κατά τη δημιουργία μιας νέας λίστας από μια λίστα, η κατανόηση λίστας είναι απλούστερη στη σύνταξη από ό,τι οι βρόχοι for.
[expression for any variable name in iterable object if conditional expression]
Εάν το στοιχείο πρόκειται να επιλεγεί μόνο από μια υπό συνθήκη έκφραση, δεν επεξεργάζεται από μια έκφραση, οπότε παίρνει την ακόλουθη μορφή
[variable name for variable name in original list if conditional expression]
Εάν η υπό συνθήκη έκφραση if μετατραπεί σε υπό συνθήκη έκφραση if not, μετατρέπεται σε άρνηση και τα στοιχεία που δεν ικανοποιούν την υπό συνθήκη έκφραση μπορούν να εξαχθούν.
Περιέχει μια συγκεκριμένη συμβολοσειρά (μερική αντιστοιχία) \ Δεν περιέχει: in
Στο «συγκεκριμένο αλφαριθμητικό στο αρχικό αλφαριθμητικό», επιστρέφει True αν το αρχικό αλφαριθμητικό περιέχει το συγκεκριμένο αλφαριθμητικό. Πρόκειται για μια υπό συνθήκη έκφραση.
Η άρνηση του in γίνεται με το not in.
l = ['oneXXXaaa', 'twoXXXbbb', 'three999aaa', '000111222']
l_in = [s for s in l if 'XXX' in s]
print(l_in)
# ['oneXXXaaa', 'twoXXXbbb']
l_in_not = [s for s in l if 'XXX' not in s]
print(l_in_not)
# ['three999aaa', '000111222']
Αντικατάσταση συγκεκριμένης συμβολοσειράς
Αν θέλετε να αντικαταστήσετε μια συμβολοσειρά από στοιχεία λίστας, χρησιμοποιήστε τη μέθοδο συμβολοσειράς replace() για κάθε στοιχείο του συμβολισμού κατανόησης λίστας.
Εάν δεν υπάρχει συμβολοσειρά προς αντικατάσταση, δεν χρειάζεται να επιλέξετε το στοιχείο στην υπό συνθήκη έκφραση if, επειδή δεν θα αλλάξει με την εφαρμογή της replace().
l_replace = [s.replace('XXX', 'ZZZ') for s in l]
print(l_replace)
# ['oneZZZaaa', 'twoZZZbbb', 'three999aaa', '000111222']
Αν θέλετε να αντικαταστήσετε ένα ολόκληρο στοιχείο που περιέχει ένα συγκεκριμένο αλφαριθμητικό, εξάγετε το με το in και επεξεργαστείτε το με τον τελεστή ternary. Ο τελεστής ternary γράφεται στην ακόλουθη μορφή.True Value if Conditional Expression else False Value
Είναι εντάξει αν το τμήμα έκφρασης του συμβολισμού κατανόησης λίστας είναι ένας τριμερής τελεστής.
l_replace_all = ['ZZZ' if 'XXX' in s else s for s in l]
print(l_replace_all)
# ['ZZZ', 'ZZZ', 'three999aaa', '000111222']
Ακολουθεί περίληψη των αποτελεσμάτων, σε παρένθεση. Εάν δεν έχετε συνηθίσει να χρησιμοποιείτε παρενθέσεις, ίσως είναι ευκολότερο να κατανοήσετε και να αποφύγετε τα λάθη. Από γραμματική άποψη, δεν υπάρχει κανένα πρόβλημα ακόμη και αν γράφετε παρενθέσεις.
[('ZZZ' if ('XXX' in s) else s) for s in l]
Η χρήση του in ως συνθήκη προκαλεί σύγχυση με τον συμβολισμό κατανόησης λίστας in, αλλά δεν είναι δύσκολο αν γνωρίζετε τη συντακτική μορφή του συμβολισμού κατανόησης λίστας και των τριμερών τελεστών.
Ξεκινάει με μια συγκεκριμένη συμβολοσειρά \ δεν ξεκινάει: startswith()
Η μέθοδος συμβολοσειράς startswith() επιστρέφει true αν η συμβολοσειρά αρχίζει με τη συμβολοσειρά που καθορίζεται στο όρισμα.
l_start = [s for s in l if s.startswith('t')]
print(l_start)
# ['twoXXXbbb', 'three999aaa']
l_start_not = [s for s in l if not s.startswith('t')]
print(l_start_not)
# ['oneXXXaaa', '000111222']
Τελειώνει με μια συγκεκριμένη συμβολοσειρά χαρακτήρων \ δεν τελειώνει: endswith()
Η μέθοδος συμβολοσειράς endswith() επιστρέφει true αν η συμβολοσειρά τελειώνει με τη συμβολοσειρά που καθορίζεται στο όρισμα.
l_end = [s for s in l if s.endswith('aaa')]
print(l_end)
# ['oneXXXaaa', 'three999aaa']
l_end_not = [s for s in l if not s.endswith('aaa')]
print(l_end_not)
# ['twoXXXbbb', '000111222']
Κρίνεται και εξάγεται κατά περίπτωση
Οι μέθοδοι συμβολοσειρών isupper(),islower() μπορούν να χρησιμοποιηθούν για να καθορίσουν αν μια συμβολοσειρά είναι μόνο κεφαλαία ή μόνο πεζά γράμματα.
l_lower = [s for s in l if s.islower()]
print(l_lower)
# ['three999aaa']
Μετατροπή κεφαλαίων και πεζών
Αν θέλετε να μετατρέψετε όλους τους χαρακτήρες σε κεφαλαία ή πεζά γράμματα, χρησιμοποιήστε τις μεθόδους string upper() και lower(). Άλλες μέθοδοι περιλαμβάνουν την capitalize(), η οποία κεφαλαιοποιεί μόνο το πρώτο γράμμα, και την swapcase(), η οποία ανταλλάσσει κεφαλαία και πεζά γράμματα.
Όπως και στο παραπάνω παράδειγμα αντικατάστασης, χρησιμοποιήστε τον τελεστή ternary αν θέλετε να επεξεργαστείτε μόνο τα στοιχεία που ικανοποιούν τη συνθήκη.
l_upper_all = [s.upper() for s in l]
print(l_upper_all)
# ['ONEXXXAAA', 'TWOXXXBBB', 'THREE999AAA', '000111222']
l_lower_to_upper = [s.upper() if s.islower() else s for s in l]
print(l_lower_to_upper)
# ['oneXXXaaa', 'twoXXXbbb', 'THREE999AAA', '000111222']
Καθορίζει αν χρησιμοποιούνται αλφαβητικοί ή αριθμητικοί χαρακτήρες και τους εξάγει
Οι μέθοδοι συμβολοσειρών isalpha() και isnumeric() μπορούν να χρησιμοποιηθούν για να προσδιοριστεί αν μια συμβολοσειρά είναι αλφαβητική, αριθμητική κ.λπ.
l_isalpha = [s for s in l if s.isalpha()]
print(l_isalpha)
# ['oneXXXaaa', 'twoXXXbbb']
l_isnumeric = [s for s in l if s.isnumeric()]
print(l_isnumeric)
# ['000111222']
Πολλαπλές συνθήκες
Το μέρος της έκφρασης υπό συνθήκη της κατανόησης λίστας μπορεί να είναι πολλαπλές συνθήκες. Μπορούν επίσης να χρησιμοποιηθούν αρνητικές συνθήκες «not».
Όταν χρησιμοποιείτε τρεις ή περισσότερες εξαρτημένες εκφράσεις, είναι ασφαλέστερο να περικλείετε κάθε ομάδα σε παρένθεση () επειδή το αποτέλεσμα θα διαφέρει ανάλογα με τη σειρά.
l_multi = [s for s in l if s.isalpha() and not s.startswith('t')]
print(l_multi)
# ['oneXXXaaa']
l_multi_or = [s for s in l if (s.isalpha() and not s.startswith('t')) or ('bbb' in s)]
print(l_multi_or)
# ['oneXXXaaa', 'twoXXXbbb']
(υπολογιστής) κανονική έκφραση
Οι κανονικές εκφράσεις επιτρέπουν εξαιρετικά ευέλικτη επεξεργασία.
Το αντικείμενο match που επιστρέφεται από την re.match() όταν ταιριάζει προσδιορίζεται πάντα ως αληθές όταν αξιολογείται με μια έκφραση υπό συνθήκη. Εάν δεν ταιριάζει, επιστρέφει None, το οποίο είναι ψευδές στην υπό συνθήκη έκφραση. Έτσι, αν θέλετε να εξάγετε μόνο τα στοιχεία που ταιριάζουν με την κανονική έκφραση, απλώς εφαρμόστε την re.match() στο τμήμα της υπό συνθήκη έκφρασης της έκφρασης κατανόησης της λίστας όπως και πριν.
import re
l = ['oneXXXaaa', 'twoXXXbbb', 'three999aaa', '000111222']
l_re_match = [s for s in l if re.match('.*XXX.*', s)]
print(l_re_match)
# ['oneXXXaaa', 'twoXXXbbb']
Η re.sub(), η οποία αντικαθιστά το τμήμα μιας κανονικής έκφρασης που ταιριάζει, είναι επίσης χρήσιμη. Για να εξαγάγετε και να αντικαταστήσετε μόνο τα στοιχεία που ταιριάζουν, απλά προσθέστε «if conditional expression».
l_re_sub_all = [re.sub('(.*)XXX(.*)', r'\2---\1', s) for s in l]
print(l_re_sub_all)
# ['aaa---one', 'bbb---two', 'three999aaa', '000111222']
l_re_sub = [re.sub('(.*)XXX(.*)', r'\2---\1', s) for s in l if re.match('.*XXX.*', s)]
print(l_re_sub)
# ['aaa---one', 'bbb---two']