Dzisiaj pytanie bardziej opisowe, chociaż będą też przykłady.

Co to jest nazwana tupla (ang. named tuple) i czym się różni od zwykłej tupli ? Kiedy należy ją użyć i jakie problemy rozwiązuje ?

Czemu używamy tupli

Tuple zaraz po listach są chyba najczęściej używanymi strukturami danychPythonie. Ja trzymam się zasady: zawsze jeśli tylko się da, użyj tupli. Tuple są lżejsze, szybsze oraz lepiej radzą sobie w świecie wielowątkowych aplikacji. Generalnie jeśli potrzebujesz trzymać swoje dane w kolekcji i nie masz zamiaru ich zmieniać, czy też dodawać do nich nowych pozycje, sięgasz po tuple. Niezmienność tupli (tupleimmutable) niejako gwarantuje nam, że co by się nie działo, nasze dane pozostaną takie jak były. Należy korzystać z tej cechy tak często jak to możliwe.

Ograniczenia tupli

Mimo wielu zalet tuple mają też wady. I nie chodzi tu o brak możliwości ich edycji. Tą cechę trzeba zaakceptować. Jeśli Ci to przeszkadza to prawdopodobnie do rozwiązania tego konkretnego problemu potrzebujesz listy albo jakiejś innej kolekcji danych. Tuple wprowadzają nam bałagan. Za przykład niech posłuży nam taka tupla:

szafa = (180, 90, 70)

Nasza tupla o nazwie szafa posiada trzy wartości. Wysokość, szerokość oraz głębokość. Jednym słowem są to wymiary tej szafy. Problem z tym, że ja to wiem bo przed chwilą to napisałem. Jeśli zajrzałbym do takiego kodu za tydzień pewnie już bym tego nie pamiętał. Co ma powiedzieć osoba, która dostaje taki kod po nas. Nie mówiąc już o tym, że nie ma żadnego sensownego sposobu by zorientować się, która wartość reprezentuje wysokość, czy też szerokość naszej szafy. Czytelność kodu ma duże znaczenie. Trzeba coś z tym zrobić.

A może słownik ?

Użycie słownika w tym przypadku znacząco zwiększy czytelność kodu:

szafa = {'wysokosc': 180, 'szerokosc':90, 'glebokosc':70}
print(szafa['wysokosc']
print(szafa)

Output:

180
{'wysokosc': 180, 'szerokosc': 90, 'glebokosc': 70}

Uzyskaliśmy ładny sposób dostępu do naszych danych. Nasz słownik ładnie też się wyświetla. To co straciliśmy to niezmienność. Słownik jest typem zmiennym, a więc w trakcie wykonywania programu możemy go modyfikować.  Nie o to nam chodziło.

A może klasa ?

Klasa wraz ze swoimi polami również będzie wygodnym kontenerem na trzymanie naszych informacji:

class Szafa:
     def __init__(self, wysokosc, szerokosc, glebokosc):
             self.wysokosc = wysokosc
             self.szerokosc = szerokosc
             self.glrbokosc = glebokosc
 
 
szafa = Szafa(180, 90, 70)
print(szafa)
print(szafa.wysokosc)

Output:

<__main__.Szafa object at 0x7fbadc148710>
180

Niestety obiekty klasy nie wyświetlają się już tak ładnie. Oczywiście można by i to naprawić poprzez implementacje odpowiedniej magicznej metody. Dodatkowo znowu mamy problem ze zmiennością naszej instancji. Obiekty klasy nie są immutable. Przydałaby się nam klasa której nie da się zmieniać.

Named tuple czyli tupla nazwana

Na ratunek przybywa nam tupla nazwana. Jest to coś pomiędzy klasą, a zwykłą tuplą. Dodatkowo jest immutable, a o to przecież nam chodziło.

from collections import namedtuple

Szafa = namedtuple('Szafa', ['wysokosc', 'szerokosc', 'glebokosc'])
szafa = Szafa(180, 90 ,70)
print(szafa.wysokosc)
print(szafa)

Output:

180
Szafa(wysokosc=180, szerokosc=90, glebokosc=70)

Teraz można odwoływać się do poszczególnych pól zarówno poprzez indeks jak w zwykłej tupli oraz za pomocą nazw parametrów.

Zachęcam do używania argumentów w postaci słów kluczowych podczas tworzenia naszej tupli szafa = Szafa(wysokosc=180, szerokosc=90, glebokosc=70)

Podsumowanie

Tuple nazwane są bardzo pomocne. To czego nam nie oferują to domyślne parametry półtuplach podczas ich tworzenia. Jako ciekawostka ten problem można też rozwiązać, ale to już temat na inny wpis. Miłej zabawy z tuplami.