Do generowania nowej listy z listy (tablicy), której elementami są ciągi znaków, przez wyodrębnianie tylko tych elementów ciągów znaków, które spełniają określone warunki, lub przez wykonywanie podstawień, konwersji itp. służą comprehensions list.
Po krótkim objaśnieniu list comprehensions, poniższe treści są objaśniane za pomocą przykładowego kodu.
- Wydobywanie na podstawie tego, czy określony ciąg znaków jest zawarty, czy nie (dopasowanie częściowe)
- Zastąp określony ciąg znaków
- Wyodrębnij, zaczynając lub nie zaczynając od określonego ciągu znaków
- Wyodrębniaj według zakończenia lub braku zakończenia określonym ciągiem znaków
- Oceniane i wyodrębniane według przypadków
- Konwertuj wielkie i małe litery
- Określa, czy używane są znaki alfabetyczne czy numeryczne, i wyodrębnia je.
- Wiele warunków
- (komputer) wyrażenie regularne
Należy pamiętać, że listy mogą przechowywać różne typy danych i różnią się ściśle od tablic. Jeśli chcesz obsługiwać tablice w procesach, które wymagają wielkości pamięci i adresów pamięci lub numerycznego przetwarzania dużych danych, użyj tablicy (biblioteka standardowa) lub NumPy.
- notacja uwzględniająca listę
- Zawiera określony ciąg znaków (dopasowanie częściowe) \NNie zawiera: in
- Zastąp określony ciąg znaków
- Zaczyna się od określonego ciągu znaków \ nie zaczyna się: startswith()
- Kończy się określonym ciągiem znaków \ nie kończy się: endswith()
- Oceniane i wyodrębniane według przypadków
- Konwertuj wielkie i małe litery
- Określa, czy używane są znaki alfabetyczne czy numeryczne, i wyodrębnia je.
- Wiele warunków
- (komputer) wyrażenie regularne
notacja uwzględniająca listę
W przypadku generowania nowej listy na podstawie listy, kompetycje list są prostsze do napisania niż pętle for.
[expression for any variable name in iterable object if conditional expression]
Jeśli element ma być wybrany tylko przez wyrażenie warunkowe, nie jest on przetwarzany przez wyrażenie, więc przyjmuje następującą postać
[variable name for variable name in original list if conditional expression]
Jeśli wyrażenie warunkowe if zostanie przekształcone w wyrażenie warunkowe if not, staje się ono negacją i można wyodrębnić elementy, które nie spełniają wyrażenia warunkowego.
Zawiera określony ciąg znaków (dopasowanie częściowe) \NNie zawiera: in
W wyrażeniu „określony łańcuch w oryginalnym łańcuchu” zwraca True, jeśli oryginalny łańcuch zawiera określony łańcuch. Jest to wyrażenie warunkowe.
Przeczenie in odbywa się za pomocą 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']
Zastąp określony ciąg znaków
Jeśli chcesz zastąpić ciąg elementów listy, użyj metody replace() dla każdego elementu w notacji listy.
Jeśli nie ma łańcucha, który ma zostać zastąpiony, nie ma potrzeby wybierania elementu w wyrażeniu warunkowym if, ponieważ nie zostanie on zmieniony przez zastosowanie funkcji replace().
l_replace = [s.replace('XXX', 'ZZZ') for s in l]
print(l_replace)
# ['oneZZZaaa', 'twoZZZbbb', 'three999aaa', '000111222']
Jeśli chcesz zastąpić cały element zawierający określony ciąg znaków, wyodrębnij go za pomocą in i przetwórz za pomocą operatora trójdzielnego. Operator trójskładnikowy zapisuje się w następującej postaci.True Value if Conditional Expression else False Value
Jeśli częścią wyrażenia w notacji rozumienia listy jest operator trójskładnikowy, to jest to w porządku.
l_replace_all = ['ZZZ' if 'XXX' in s else s for s in l]
print(l_replace_all)
# ['ZZZ', 'ZZZ', 'three999aaa', '000111222']
Poniżej znajduje się podsumowanie wyników, ujęte w nawiasy. Jeśli nie jesteś przyzwyczajony do używania nawiasów, może to ułatwić Ci zrozumienie i uniknięcie błędów. Z gramatycznego punktu widzenia nie ma problemu nawet z zapisem nawiasów.
[('ZZZ' if ('XXX' in s) else s) for s in l]
Użycie in jako warunku jest mylące w przypadku notacji listowej in, ale nie jest to trudne, jeśli zna się formę składniową notacji listowej i operatorów trójskładnikowych.
Zaczyna się od określonego ciągu znaków \ nie zaczyna się: startswith()
Metoda string startswith() zwraca wartość true, jeśli łańcuch zaczyna się od łańcucha określonego w argumencie.
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']
Kończy się określonym ciągiem znaków \ nie kończy się: endswith()
Metoda string endswith() zwraca wartość true, jeśli łańcuch kończy się łańcuchem podanym w argumencie.
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']
Oceniane i wyodrębniane według przypadków
Metody łańcuchowe isupper(),islower() mogą być użyte do określenia, czy łańcuch jest całkowicie duży czy mały.
l_lower = [s for s in l if s.islower()]
print(l_lower)
# ['three999aaa']
Konwertuj wielkie i małe litery
Jeśli chcesz przekonwertować wszystkie znaki na wielkie lub małe litery, użyj metod łańcuchowych upper() i lower(). Inne metody to capitalize(), która kapitalizuje tylko pierwszą literę, oraz swapcase(), która zamienia wielkie i małe litery.
Podobnie jak w powyższym przykładzie podstawiania, należy użyć operatora trójskładnikowego, jeśli chcemy przetwarzać tylko elementy spełniające dany warunek.
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']
Określa, czy używane są znaki alfabetyczne czy numeryczne, i wyodrębnia je.
Metody łańcuchowe isalpha() i isnumeric() mogą być użyte do określenia, czy łańcuch jest alfabetyczny, numeryczny itd.
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']
Wiele warunków
Część wyrażenia warunkowego w listach może zawierać wiele warunków. Można również używać warunków ujemnych typu „nie”.
W przypadku użycia trzech lub więcej wyrażeń warunkowych bezpieczniej jest ująć każdą grupę w nawiasy (), ponieważ wynik będzie się różnił w zależności od kolejności.
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']
(komputer) wyrażenie regularne
Wyrażenia regularne pozwalają na bardzo elastyczne przetwarzanie danych.
Obiekt dopasowania zwrócony przez re.match(), gdy jest dopasowany, jest zawsze określany jako prawdziwy, gdy jest obliczany za pomocą wyrażenia warunkowego. Jeśli nie pasuje, zwraca Brak, czyli fałsz w wyrażeniu warunkowym. Tak więc, jeśli chcesz wyodrębnić tylko elementy pasujące do wyrażenia regularnego, po prostu zastosuj re.match() do części wyrażenia warunkowego wyrażenia złożonego listy, tak jak poprzednio.
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']
przydatna jest również funkcja re.sub(), która zastępuje dopasowaną część wyrażenia regularnego. Aby wyodrębnić i zastąpić tylko dopasowane elementy, wystarczy dodać „jeśli wyrażenie warunkowe”.
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']