Metody append() i extend() dla list w Pythonie służą do dodawania elementów, jednak robią to w zasadniczo różny sposób:
append(obj) dodaje jeden element (dowolny obiekt — w tym listę) na koniec pierwotnej listyextend(iterable) dodaje wszystkie elementy iterowalnego obiektu jeden po drugim (jakby "rozszerza" go przy dodawaniu)Przykład:
lst = [1, 2, 3] lst.append([4, 5]) # Wynik: [1, 2, 3, [4, 5]] lst = [1, 2, 3] lst.extend([4, 5]) # Wynik: [1, 2, 3, 4, 5]
Taka różnica często staje się przyczyną błędów logicznych, gdy oczekuje się "płaskiej" listy, a otrzymuje się zagnieżdżone.
Co się stanie, jeśli zrobisz
list1 = [1, 2]; list2 = [3, 4]; list1.append(list2)? Jak wygląda list1? Czym różni się to odlist1.extend(list2)?
Odpowiedź:
list1.append(list2) wynik: [1, 2, [3, 4]] — drugi lista została dodana jako jeden element (zagnieżdżona lista)list1.extend(list2) wynik: [1, 2, 3, 4] — elementy drugiej listy zostały "rozszerzone" i dodane jako oddzielne elementyHistoria
Programista podczas łączenia wyników parsowania z kilku plików robił
output.append(parsed_lines). W rezultacie zamiast długiej płaskiej listy otrzymywał listę list (jeden element na każdy plik), co psuło dalsze przetwarzanie — w szczególności funkcje, które oczekiwały na sekwencję ciągów, zaczęły zgłaszać błędy na danych wejściowych.
Historia
W projekcie używano extend do dodania ciągu w formie "foo" (więc ciąg był traktowany jako iterowalny). Doprowadziło to do sytuacji, w której znaki ciągu stały się oddzielnymi elementami listy:
['f', 'o', 'o']zamiast oczekiwanego "foo".
Historia
Przy serializacji danych do przesłania w formacie JSON do końcowej listy stosowano append/extend w pętli bez zrozumienia różnicy. W rezultacie otrzymywano struktury, które naruszały schemat, przez co część mikroserwisów zaczynała padać na etapie walidacji lub działać niepoprawnie.