Zanurkuj w Pythonie/Odwzorowywanie listy
Odwzorowywanie list
[edytuj]Jedną z bardzo użytecznych cech Pythona są wyrażenia listowe (ang. list comprehension), które pozwalają nam w zwięzły sposób odwzorować pewną listę na inną, wykonując na każdym jej elemencie pewną funkcję.
>>> li = [1, 9, 8, 4] >>> [element*2 for element in li] #(1) [2, 18, 16, 8] >>> li #(2) [1, 9, 8, 4] >>> li = [elem*2 for elem in li] #(3) >>> li [2, 18, 16, 8]
- Aby zrozumieć o co w tym chodzi, spójrzmy na to od strony prawej do lewej.
li
jest listą, którą odwzorowujemy. Python przechodzi po każdym elemencieli
, tymczasowo przypisując wartość każdego elementu do zmiennejelement
, a następnie wyznacza wartość funkcjielement*2
i wstawia wynik do nowej, zwracanej listy. - Wyrażenia listowe nie zmieniają oryginalnej listy.
- Zwracany wynik możemy przypisać do zmiennej, którą odwzorowujemy. Nie spowoduje to żadnych problemów. Python tworzy nową listę w pamięci, a kiedy operacja odwzorowywania listy dobiegnie końca, do zmiennej zostanie przypisana lista znajdująca się w pamięci.
W funkcji buildConnectionString
zadeklarowanej w rozdziale 2 skorzystaliśmy z wyrażeń listowych:
["%s=%s" % (k, v) for k, v in params.items()]
Zauważmy, że najpierw wykonujemy funkcję items
, znajdującą się w słowniku params
. Funkcja ta zwraca wszystkie dane znajdujące się w słowniku w postaci listy krotek.
keys
, values
i items
>>> params = {"server":"mpilgrim", "database":"master", "uid":"sa", "pwd":"secret"} >>> params.keys() #(1) ['pwd', 'database', 'uid', 'server'] >>> params.values() #(2) ['secret', 'master', 'sa', 'mpilgrim'] >>> params.items() #(3) [('pwd', 'secret'), ('database', 'master'), ('uid', 'sa'), ('server', 'mpilgrim')]
- W słowniku metoda
keys
zwraca listę wszystkich kluczy. Lista ta nie jest uporządkowana zgodnie z kolejnością, z jaką definiowaliśmy słownik (pamiętamy, że elementy w słowniku są nieuporządkowane). - Metoda
values
zwraca listę wszystkich wartości. Lista ta jest zgodna z porządkiem listy zwracanej przez metodękeys
, czyli dla wszystkich wartościx
zachodziparams.values()[x] == params[params.keys()[x]]
. - Metoda
items
zwraca listę krotek w formie(klucz, wartość)
. Lista zawiera wszystkie dane ze słownika.
Spójrzmy jeszcze raz na funkcję buildConnectionString
. Przyjmuje ona listę params.items()
, odwzorowuje ją na nową listę, korzystając dla każdego elementu z formatowania łańcucha znaków. Nowa lista ma tyle samo elementów co params.items()
, lecz każdy element nowej listy jest łańcuchem znaków, który zawiera zarówno klucz, jak i skojarzoną z nim wartość ze słownika params
.
buildConnectionString
>>> params = {"server":"mpilgrim", "database":"master", "uid":"sa", "pwd":"secret"} >>> params.items() [('server', 'mpilgrim'), ('uid', 'sa'), ('database', 'master'), ('pwd', 'secret')] >>> [k for k, v in params.items()] #(1) ['server', 'uid', 'database', 'pwd'] >>> [v for k, v in params.items()] #(2) ['mpilgrim', 'sa', 'master', 'secret'] >>> ["%s=%s" % (k, v) for k, v in params.items()] #(3) ['server=mpilgrim', 'uid=sa', 'database=master', 'pwd=secret']
- Wykonując iteracje po liście
params.items()
używamy dwóch zmiennych. Zauważmy, że w ten sposób korzystamy w pętli z wielozmiennego przypisania. Pierwszym elementemparams.items()
jest('server', 'mpilgrim')
, dlatego też podczas pierwszej iteracji odwzorowywania listy zmiennak
będzie przechowywała wartość'server'
, av
wartość'mpilgrim'
. W tym przypadku ignorujemy wartośćv
, dołączając tylko wartość znajdującą się wk
do zwracanej listy. Otrzymamy taki sam wynik, gdy wywołamyparams.keys()
. - W tym miejscu wykonujemy to samo, ale zamiast zmiennej
v
ignorujemy zmiennąk
. Otrzymamy taki sam wynik, jakbyśmy wywołaliparams.values()
. - Dzięki temu, że przerobiliśmy obydwa poprzednie przykłady i skorzystaliśmy z formatowania łańcucha znaków, otrzymaliśmy listę łańcuchów znaków. Każdy łańcuch znaków tej listy zawiera zarówno klucz, jak i wartość pewnego elementu ze słownika. Wynik wygląda podobnie do wyjścia pierwszego programu. Ponadto porządek został taki sam, jaki był w słowniku.
Materiały dodatkowe
[edytuj]- Python Tutorial omawia inny sposób odwzorowywania listy -- za pomocą wbudowanej funkcji
map
. - Python Tutorial pokazuje kilka przykładów, jak można korzystać z wyrażeń listowych.