Porównywanie ciągów przy użyciu Pythona

W Pythonie łańcuchy są sekwencjami znaków, które są skutecznie przechowywane w pamięci jako obiekt. Każdy obiekt można zidentyfikować za pomocą id() sposób, jak widać poniżej. Python próbuje ponownie wykorzystać obiekty w pamięci, które mają tę samą wartość, co również sprawia, że ​​porównywanie obiektów jest bardzo szybkie w Pythonie:

$ python
Python 3.9.0 (v3.9.0:9cf6752276, Oct  5 2020, 11:29:23) 
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> a = "abc"
>>> b = "abc"
>>> c = "def"
>>> print (id(a), id(b), id(c))
(139949123041320, 139949123041320, 139949122390576)
>>> quit()

Aby porównać łańcuchy, Python oferuje kilka różnych operatorów. Najpierw wyjaśnimy je bardziej szczegółowo poniżej. Po drugie, omówimy oba string oraz re moduły, które zawierają metody do obsługi dopasowań bez rozróżniania wielkości liter i niedokładnych dopasowań. Po trzecie, aby poradzić sobie z ciągami wielowierszowymi moduł difflib jest całkiem poręczny. Szereg przykładów pomoże ci zrozumieć, jak z nich korzystać.

Porównaj ciągi z operatorami The == i !=

Jako podstawowy operator porównania, którego będziesz chciał użyć == i !=. Działają dokładnie w taki sam sposób, jak wartości całkowite i zmiennoprzecinkowe. The == operator zwraca True jeśli istnieje dokładne dopasowanie, w przeciwnym razie False będzie zwrócony. Dla kontrastu, != operator zwraca True jeśli nie ma dopasowania i w przeciwnym razie zwraca False. Lista 1 demonstruje to.

W for pętli, ciąg zawierający nazwę szwajcarskiego miasta „Lozanna” jest porównywany z wpisem z listy innych miejscowości, a wynik porównania jest drukowany na stdout.

Lista 1:


listOfPlaces = ["Berlin", "Paris", "Lausanne"]
currentCity = "Lausanne"

for place in listOfPlaces:
    print (f"comparing {place} with {currentCity}: %{place == currentCity}")

Uruchamianie skryptu Pythona z góry danych wyjściowych wygląda następująco:

$ python3 comparing-strings.py
comparing Berlin with Lausanne: False
comparing Paris with Lausanne: False
comparing Lausanne with Lausanne: True

Połączenia == i is Operatorzy

Python ma dwa operatory porównania == i is. Na pierwszy rzut oka wydają się być takie same, ale w rzeczywistości tak nie jest.

== porównuje dwie zmienne na podstawie wartości, którą reprezentują. Dla kontrastu, is operator porównuje dwie zmienne na podstawie identyfikatora obiektu w pamięci.

John (Doe) i John (Moe) nazywają się John. Gdybyśmy mogli zredukować ich do samych imion, mieliby taką samą wartość, ale wciąż jakościowo dwie różne osoby.

Następny przykład pokazuje, że dla trzech zmiennych z wartościami łańcuchowymi. Dwie zmienne a i b mają tę samą wartość, a Python odwołuje się do tego samego obiektu, aby zminimalizować zużycie pamięci.

Jest to domyślnie wykonywane dla prostych typów i łańcuchów, ale nie dla innych obiektów:

>>> a = 'hello'
>>> b = 'hello'
>>> c = 'world'
>>> a is b
True
>>> a is c
False
>>> id(a)
140666888153840
>>> id(b)
140666888153840
>>> 

Gdy tylko wartość się zmieni, Python przywróci obiekt i przypisze zmienną. W następnym fragmencie kodu b otrzymuje wartość 2, a następnie b i c odnoszą się do tego samego obiektu:

>>> b = 'world'
>>> id(b)
140666888154416
>>> id(c)
140666888154416

Więcej operatorów porównania

Do porównania dotyczącego porządku leksykograficznego można użyć operatorów porównania <, >, <=, >=. Samo porównanie odbywa się znak po znaku. Kolejność zależy od kolejności znaków w alfabecie. Ta kolejność zależy od tablicy znaków, która jest używana na twoim komputerze podczas wykonywania kodu Pythona.

Pamiętaj, że w kolejności rozróżniana jest wielkość liter. Jako przykład alfabetu łacińskiego, „Bus” występuje przed „bus”. Lista 2 pokazuje, jak te operatory porównania działają w praktyce.

Lista 2:


listOfPlaces = ["Berlin", "Paris", "Lausanne"]
currentCity = "Lausanne"

for place in listOfPlaces:
    if place < currentCity:
            print (f"{place} comes before {currentCity}")
    elif place > currentCity:
            print (f"{place} comes after {currentCity}")
    else:
            print (f"{place} is equal to {currentCity}")

Uruchamianie skryptu Pythona z góry danych wyjściowych wygląda następująco:

$ python3 comparing-strings-order.py
Berlin comes before Lausanne
Paris comes after Lausanne
Lausanne is equal to Lausanne

Porównywanie ciągów znaków bez rozróżniania wielkości liter

Poprzednie przykłady koncentrowały się na dokładnych dopasowaniach między ciągami. Aby umożliwić porównywanie bez rozróżniania wielkości liter, Python oferuje specjalne metody łańcuchowe, takie jak upper() i lower(). Oba są bezpośrednio dostępne jako metody odpowiedniego obiektu łańcuchowego.

upper() konwertuje cały ciąg na wielkie litery i lower() odpowiednio małymi literami. Oparte na Lista 1 następna lista pokazuje, jak używać lower() Metoda.

Zapoznaj się z naszym praktycznym, praktycznym przewodnikiem dotyczącym nauki Git, zawierającym najlepsze praktyki, standardy przyjęte w branży i dołączoną ściągawkę. Zatrzymaj polecenia Google Git, a właściwie uczyć się to!

Lista 3:


listOfPlaces = ["Berlin", "Paris", "Lausanne"]
currentCity = "lausANne"

for place in listOfPlaces:
    print (f"comparing {place} with {place.lower() == currentCity.lower()}: {currentCity}")

Dane wyjściowe są następujące:

$ python3 comparing-strings-case-insensitive.py
comparing Berlin with lausANne: False
comparing Paris with lausANne: False
comparing Lausanne with lausANne: True

Porównaj ciągi przy użyciu wyrażeń regularnych (RegEx)

A Wyrażenie regularne – lub w skrócie „regex” – definiuje określony wzorzec znaków.

Aby skorzystać z tego mechanizmu w Pythonie, zaimportuj plik re moduł najpierw i zdefiniuj konkretny wzór, następnie. Ponownie, poniższy przykład jest oparty na Lista 1. Wzorzec wyszukiwania pasuje do słowa „zatoka” i zaczyna się od małej lub dużej litery. Dokładniej, poniższy kod Pythona znajduje wszystkie ciągi znaków, w których występuje wzorzec wyszukiwania, bez względu na to, w którym miejscu łańcucha — na początku, w środku lub na końcu.

Lista 4:


import re


listOfPlaces = ["Bayswater", "Table Bay", "Bejing", "Bombay"]


pattern = re.compile("[Bb]ay")

for place in listOfPlaces:
    if pattern.search(place):
        print (f"{place} matches the search pattern")

Dane wyjściowe są następujące i pasują do „Bayswater”, „Table Bay” i „Bombay” z listy miejsc:

$ python3 comparing-strings-re.py
Bayswater matches the search pattern
Table Bay matches the search pattern
Bombay matches the search pattern

Porównania wielu linii i list

Jak dotąd nasze porównania dotyczyły tylko kilku słów. Używając difflib Moduł Python oferuje również sposób porównywania ciągów wielowierszowych i całych list słów. Dane wyjściowe można skonfigurować zgodnie z różnymi formatami narzędzi do porównywania.

Następny przykład (Lista 5) porównuje dwa ciągi wielowierszowe wiersz po wierszu i pokazuje zarówno usunięcia, jak i uzupełnienia. Po inicjalizacji Differ obiekt w wierszu 12 porównanie jest wykonywane przy użyciu metody compare() metoda w wierszu 15. Wynik wypisywany jest na standardowe wyjście:


import difflib
 


original = ["About the IIS", "", "IIS 8.5 has several improvements related", "to performance in large-scale scenarios, such", "as those used by commercial hosting providers and Microsoft's", "own cloud offerings."]


edited = ["About the IIS", "", "It has several improvements related", "to performance in large-scale scenarios."]


d = difflib.Differ()
 

diff = d.compare(original, edited)
 

print ('n'.join(diff))

Uruchomienie skryptu tworzy dane wyjściowe, jak pokazano poniżej. Linie z delecjami są oznaczone przez - znaki natomiast wiersze z dopiskami zaczynają się od a + podpisać. Ponadto linie ze zmianami zaczynają się od znaku zapytania. Zmiany są wskazywane za pomocą ^ znaki w odpowiednim miejscu. Linie bez wskaźnika są nadal takie same:

$ python comparing-strings-difflib.py
  About the IIS
  
- IIS 8.5 has several improvements related
?  ^^^^^^

+ It has several improvements related
?  ^

- to performance in large-scale scenarios, such
?                                        ^^^^^^

+ to performance in large-scale scenarios.
?                                        ^

- as those used by commercial hosting providers and Microsoft's
- own cloud offerings.

Wnioski

W tym artykule poznałeś różne sposoby porównywania ciągów znaków w Pythonie. Mamy nadzieję, że ten przegląd pomoże Ci skutecznie programować w życiu Twojego programisty.

Podziękowania

Autorka dziękuje Mandy Neumeyer za wsparcie w przygotowaniu artykułu.

Znak czasu:

Więcej z Nadużycie stosu