{"id":1528,"date":"2026-04-17T15:48:20","date_gmt":"2026-04-17T13:48:20","guid":{"rendered":"https:\/\/trzykody.pl\/?p=1528"},"modified":"2026-04-28T15:55:05","modified_gmt":"2026-04-28T13:55:05","slug":"reversed-zwraca-odwrocony-iterator","status":"publish","type":"post","link":"https:\/\/trzykody.pl\/index.php\/2026\/04\/17\/reversed-zwraca-odwrocony-iterator\/","title":{"rendered":"Reversed \u2013 zwraca odwr\u00f3cony iterator"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Praca z kolekcjami danych bardzo cz\u0119sto ko\u0144czy si\u0119 nie na ich odczycie, ale na potrzebie przej\u015bcia po elementach w odwrotnej kolejno\u015bci. Dotyczy to list, tablic, ci\u0105g\u00f3w znak\u00f3w, wynik\u00f3w oblicze\u0144 i struktur u\u017cywanych w algorytmach. Odwracanie kolejno\u015bci nie zawsze oznacza fizyczn\u0105 zmian\u0119 danych w pami\u0119ci &#8211; cz\u0119sto wystarczy iterator, kt\u00f3ry pozwala przej\u015b\u0107 po elementach od ko\u0144ca do pocz\u0105tku bez kopiowania ca\u0142ej struktury. W Pythonie w\u0142a\u015bnie do tego s\u0142u\u017cy Reversed \u2013 zwraca odwr\u00f3cony iterator.<\/p>\n\n\n\n<div class=\"wp-block-rank-math-toc-block\" id=\"rank-math-toc\"><h2>Spis Tre\u015bci<\/h2><nav><ol><li><a href=\"#reversed-zwraca-odwrocony-iterator-i-pozwala-przechodzic-po-danych-bez-kopiowania-calej-struktury\">Reversed \u2013 zwraca odwr\u00f3cony iterator i pozwala przechodzi\u0107 po danych bez kopiowania ca\u0142ej struktury<\/a><\/li><li><a href=\"#roznica-miedzy-reversed-reverse-oraz-odwracaniem-przez-indeksowanie-ma-znaczenie-wydajnosciowe\">R\u00f3\u017cnica mi\u0119dzy reversed(), reverse() oraz odwracaniem przez indeksowanie ma znaczenie wydajno\u015bciowe<\/a><ol><li><a href=\"#reversed\">reversed()<\/a><\/li><li><a href=\"#list-reverse\">list.reverse()<\/a><\/li><li><a href=\"#slicing-1\">slicing [::-1]<\/a><\/li><\/ol><\/li><li><a href=\"#reversed-zwraca-odwrocony-iterator-w-obiektach-wlasnych-tylko-wtedy-gdy-spelnione-sa-warunki-protokolu-iteracji\">Reversed \u2013 zwraca odwr\u00f3cony iterator w obiektach w\u0142asnych tylko wtedy, gdy spe\u0142nione s\u0105 warunki protoko\u0142u iteracji<\/a><\/li><li><a href=\"#zastosowanie-w-algorytmach-stosach-parsowaniu-i-analizie-danych-sekwencyjnych\">Zastosowanie w algorytmach, stosach, parsowaniu i analizie danych sekwencyjnych<\/a><ol><li><a href=\"#przechodzenie-po-stosie\">Przechodzenie po stosie<\/a><\/li><li><a href=\"#analiza-tekstu-od-konca\">Analiza tekstu od ko\u0144ca<\/a><\/li><li><a href=\"#dynamic-programming-i-tablice-pomocnicze\">Dynamic programming i tablice pomocnicze<\/a><\/li><\/ol><\/li><li><a href=\"#reversed-zwraca-odwrocony-iterator-rowniez-w-innych-jezykach-choc-mechanizm-wyglada-inaczej\">Reversed \u2013 zwraca odwr\u00f3cony iterator r\u00f3wnie\u017c w innych j\u0119zykach, cho\u0107 mechanizm wygl\u0105da inaczej<\/a><ol><li><a href=\"#c\">C++<\/a><\/li><li><a href=\"#c-1\">C<\/a><\/li><li><a href=\"#php\">PHP<\/a><\/li><\/ol><\/li><li><a href=\"#wzory-i-zaleznosci-pamieciowe-przy-pracy-z-iteratorami-oraz-kopiowaniem-danych\">Wzory i zale\u017cno\u015bci pami\u0119ciowe przy pracy z iteratorami oraz kopiowaniem danych<\/a><\/li><li><a href=\"#najczestsze-bledy-i-pulapki-ktore-powoduja-niepoprawne-dzialanie-kodu\">Najcz\u0119stsze b\u0142\u0119dy i pu\u0142apki, kt\u00f3re powoduj\u0105 niepoprawne dzia\u0142anie kodu<\/a><ol><li><a href=\"#zuzycie-iteratora-tylko-raz\">Zu\u017cycie iteratora tylko raz<\/a><\/li><li><a href=\"#oczekiwanie-zmiany-oryginalnej-listy\">Oczekiwanie zmiany oryginalnej listy<\/a><\/li><li><a href=\"#proba-uzycia-na-obiekcie-niesekwencyjnym\">Pr\u00f3ba u\u017cycia na obiekcie niesekwencyjnym<\/a><\/li><li><a href=\"#niepotrzebne-kopiowanie-danych\">Niepotrzebne kopiowanie danych<\/a><\/li><\/ol><\/li><li><a href=\"#faq\">FAQ<\/a><ol><li><a href=\"#czy-reversed-dziala-na-stringach\">Czy reversed() dzia\u0142a na stringach?<\/a><\/li><li><a href=\"#czy-reversed-dziala-na-slownikach\">Czy reversed() dzia\u0142a na s\u0142ownikach?<\/a><\/li><li><a href=\"#czy-reverse-jest-szybsze-niz-reversed\">Czy reverse() jest szybsze ni\u017c reversed()?<\/a><\/li><li><a href=\"#czy-mozna-uzywac-tego-w-petli-for-bez-list\">Czy mo\u017cna u\u017cywa\u0107 tego w p\u0119tli for bez list()?<\/a><\/li><li><a href=\"#czy-slicing-1-jest-bledem\">Czy slicing [::-1] jest b\u0142\u0119dem?<\/a><\/li><\/ol><\/li><\/ol><\/nav><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"reversed-zwraca-odwrocony-iterator-i-pozwala-przechodzic-po-danych-bez-kopiowania-calej-struktury\">Reversed \u2013 zwraca odwr\u00f3cony iterator i pozwala przechodzi\u0107 po danych bez kopiowania ca\u0142ej struktury<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Funkcja <code>reversed()<\/code> w Pythonie zwraca iterator dzia\u0142aj\u0105cy od ko\u0144ca kolekcji do pocz\u0105tku. To wa\u017cne rozr\u00f3\u017cnienie &#8211; nie zwraca nowej listy, tylko obiekt iteratora, kt\u00f3ry kolejno udost\u0119pnia elementy w odwrotnej kolejno\u015bci.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To oznacza dwie praktyczne rzeczy:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>nie ma natychmiastowego kopiowania wszystkich danych,<\/li>\n\n\n\n<li>pami\u0119\u0107 jest wykorzystywana oszcz\u0119dniej ni\u017c przy pe\u0142nym odwr\u00f3ceniu listy.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Dla ma\u0142ych danych r\u00f3\u017cnica bywa niewielka, ale przy listach licz\u0105cych setki tysi\u0119cy lub miliony element\u00f3w ma to ju\u017c realne znaczenie.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Najprostsza sk\u0142adnia wygl\u0105da tak:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Operacja<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>Python<\/td><td><code>wynik = reversed(lista)<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Je\u017celi chcemy zobaczy\u0107 wynik jako list\u0119, trzeba jawnie go zamieni\u0107:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Operacja<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>Python<\/td><td><code>print(list(reversed([1, 2, 3, 4])))<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Wynik:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Wej\u015bcie<\/th><th>Wynik<\/th><\/tr><\/thead><tbody><tr><td><code>[1, 2, 3, 4]<\/code><\/td><td><code>[4, 3, 2, 1]<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">To zachowanie r\u00f3\u017cni si\u0119 od metod, kt\u00f3re faktycznie modyfikuj\u0105 dane, np. <code>list.reverse()<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">W praktyce bardzo cz\u0119sto spotyka si\u0119 b\u0142\u0105d pocz\u0105tkuj\u0105cych: kto\u015b oczekuje, \u017ce <code>reversed()<\/code> zmieni oryginaln\u0105 list\u0119. Nie zmieni. Zwraca tylko iterator.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Przyk\u0142ad:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>J\u0119zyk<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>Python<\/td><td><code>a = [10, 20, 30]<\/code><\/td><\/tr><tr><td>Python<\/td><td><code>b = reversed(a)<\/code><\/td><\/tr><tr><td>Python<\/td><td><code>print(a)<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Wynik nadal b\u0119dzie:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Wynik<\/th><\/tr><\/thead><tbody><tr><td><code>[10, 20, 30]<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Oryginalna struktura pozostaje bez zmian.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"roznica-miedzy-reversed-reverse-oraz-odwracaniem-przez-indeksowanie-ma-znaczenie-wydajnosciowe\">R\u00f3\u017cnica mi\u0119dzy reversed(), reverse() oraz odwracaniem przez indeksowanie ma znaczenie wydajno\u015bciowe<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">W praktyce istniej\u0105 trzy najcz\u0119\u015bciej u\u017cywane sposoby pracy z odwr\u00f3con\u0105 kolejno\u015bci\u0105:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>reversed()<\/code><\/li>\n\n\n\n<li><code>list.reverse()<\/code><\/li>\n\n\n\n<li><code>[::-1]<\/code><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Na pierwszy rzut oka wygl\u0105daj\u0105 podobnie, ale dzia\u0142aj\u0105 inaczej.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"reversed\">reversed()<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Zwraca iterator.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Nie modyfikuje oryginalnej listy.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dobre rozwi\u0105zanie, gdy trzeba tylko przej\u015b\u0107 po danych od ko\u0144ca.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"list-reverse\">list.reverse()<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">To metoda listy.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Modyfikuje list\u0119 \u201ew miejscu\u201d, czyli bez tworzenia nowego obiektu.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Po wykonaniu tej operacji oryginalna kolejno\u015b\u0107 zostaje utracona.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"slicing-1\">slicing <code>[::-1]<\/code><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Tworzy now\u0105 kopi\u0119 listy w odwrotnej kolejno\u015bci.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Wygodne, ale przy du\u017cych danych koszt pami\u0119ci mo\u017ce by\u0107 istotny.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Por\u00f3wnanie:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Metoda<\/th><th>Modyfikuje orygina\u0142<\/th><th>Tworzy kopi\u0119<\/th><th>Zwraca iterator<\/th><\/tr><\/thead><tbody><tr><td><code>reversed()<\/code><\/td><td>nie<\/td><td>nie<\/td><td>tak<\/td><\/tr><tr><td><code>reverse()<\/code><\/td><td>tak<\/td><td>nie<\/td><td>nie<\/td><\/tr><tr><td><code>[::-1]<\/code><\/td><td>nie<\/td><td>tak<\/td><td>nie<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Przyk\u0142ad:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>J\u0119zyk<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>Python<\/td><td><code>a = [1,2,3,4]<\/code><\/td><\/tr><tr><td>Python<\/td><td><code>b = a[::-1]<\/code><\/td><\/tr><tr><td>Python<\/td><td><code>a.reverse()<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Po tej operacji:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Zmienna<\/th><th>Warto\u015b\u0107<\/th><\/tr><\/thead><tbody><tr><td><code>a<\/code><\/td><td><code>[4,3,2,1]<\/code><\/td><\/tr><tr><td><code>b<\/code><\/td><td><code>[4,3,2,1]<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">R\u00f3\u017cnica jest taka, \u017ce <code>b<\/code> jest now\u0105 list\u0105, a <code>a<\/code> zosta\u0142a zmieniona.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">W systemach przetwarzaj\u0105cych du\u017ce dane to nie jest detal. Kopiowanie milionowych struktur potrafi kosztowa\u0107 sekundy czasu i setki MB RAM.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"reversed-zwraca-odwrocony-iterator-w-obiektach-wlasnych-tylko-wtedy-gdy-spelnione-sa-warunki-protokolu-iteracji\">Reversed \u2013 zwraca odwr\u00f3cony iterator w obiektach w\u0142asnych tylko wtedy, gdy spe\u0142nione s\u0105 warunki protoko\u0142u iteracji<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Nie ka\u017cda struktura mo\u017ce zosta\u0107 u\u017cyta z <code>reversed()<\/code> automatycznie.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Python wymaga spe\u0142nienia jednego z dw\u00f3ch warunk\u00f3w:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>obiekt implementuje metod\u0119 <code>__reversed__()<\/code><\/li>\n\n\n\n<li>albo posiada jednocze\u015bnie <code>__len__()<\/code> oraz <code>__getitem__()<\/code><\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">To wa\u017cne przy pisaniu w\u0142asnych struktur danych.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Przyk\u0142ad w\u0142asnego obiektu:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>J\u0119zyk<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>Python<\/td><td><code>class Dane:<\/code><\/td><\/tr><tr><td>Python<\/td><td><code>def __init__(self):<\/code><\/td><\/tr><tr><td>Python<\/td><td><code>self.x = [10, 20, 30]<\/code><\/td><\/tr><tr><td>Python<\/td><td><code>def __len__(self):<\/code><\/td><\/tr><tr><td>Python<\/td><td><code>return len(self.x)<\/code><\/td><\/tr><tr><td>Python<\/td><td><code>def __getitem__(self, i):<\/code><\/td><\/tr><tr><td>Python<\/td><td><code>return self.x[i]<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Teraz:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>J\u0119zyk<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>Python<\/td><td><code>for i in reversed(Dane()):<\/code><\/td><\/tr><tr><td>Python<\/td><td><code>print(i)<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">zadzia\u0142a poprawnie.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Bez tego pojawi si\u0119 wyj\u0105tek <code>TypeError<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">W projektach produkcyjnych taki problem pojawia si\u0119 cz\u0119sto przy w\u0142asnych kontenerach, wrapperach bazodanowych albo strukturach pomocniczych w bibliotekach.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Warto pami\u0119ta\u0107: iterator odwr\u00f3cony nie jest \u201emagiczny\u201d, Python musi wiedzie\u0107, jak dosta\u0107 si\u0119 do ostatniego elementu i jak przechodzi\u0107 wstecz.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"zastosowanie-w-algorytmach-stosach-parsowaniu-i-analizie-danych-sekwencyjnych\">Zastosowanie w algorytmach, stosach, parsowaniu i analizie danych sekwencyjnych<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Odwr\u00f3cona iteracja jest bardzo praktyczna i nie jest tylko ciekawostk\u0105 sk\u0142adni.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"przechodzenie-po-stosie\">Przechodzenie po stosie<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Struktura stosu dzia\u0142a zgodnie z zasad\u0105 LIFO &#8211; ostatni wszed\u0142, pierwszy wyszed\u0142.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Cz\u0119sto chcemy przejrze\u0107 histori\u0119 operacji od najnowszej do najstarszej.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>J\u0119zyk<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>Python<\/td><td><code>operacje = [\"logowanie\", \"edycja\", \"zapis\", \"wylogowanie\"]<\/code><\/td><\/tr><tr><td>Python<\/td><td><code>for x in reversed(operacje):<\/code><\/td><\/tr><tr><td>Python<\/td><td><code>print(x)<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">To jest naturalny przypadek u\u017cycia.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"analiza-tekstu-od-konca\">Analiza tekstu od ko\u0144ca<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Parsery, kompilatory i walidatory sk\u0142adni czasem analizuj\u0105 dane od ko\u0144ca, np. przy sprawdzaniu nawias\u00f3w lub ko\u0144c\u00f3wek sk\u0142adniowych.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Przyk\u0142ad:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>J\u0119zyk<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>Python<\/td><td><code>tekst = \"raport_final_v2.txt\"<\/code><\/td><\/tr><tr><td>Python<\/td><td><code>for znak in reversed(tekst):<\/code><\/td><\/tr><tr><td>Python<\/td><td><code>print(znak)<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Dzi\u0119ki temu mo\u017cna szybciej szuka\u0107 rozszerzenia pliku lub sufiksu.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"dynamic-programming-i-tablice-pomocnicze\">Dynamic programming i tablice pomocnicze<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Niekt\u00f3re algorytmy wymagaj\u0105 przechodzenia od ko\u0144ca, \u017ceby nie nadpisywa\u0107 potrzebnych jeszcze danych.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Typowy przyk\u0142ad to problem plecakowy lub obliczenia na prefiksach i sufiksach.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Schemat:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Zastosowanie<\/th><th>Kierunek iteracji<\/th><\/tr><\/thead><tbody><tr><td>prefiksy<\/td><td>od pocz\u0105tku<\/td><\/tr><tr><td>sufiksy<\/td><td>od ko\u0144ca<\/td><\/tr><tr><td>DP 1D<\/td><td>cz\u0119sto od ko\u0144ca<\/td><\/tr><tr><td>stos operacji<\/td><td>od ko\u0144ca<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Tu iterator odwr\u00f3cony jest bardzo wygodny i bezpieczny.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"reversed-zwraca-odwrocony-iterator-rowniez-w-innych-jezykach-choc-mechanizm-wyglada-inaczej\">Reversed \u2013 zwraca odwr\u00f3cony iterator r\u00f3wnie\u017c w innych j\u0119zykach, cho\u0107 mechanizm wygl\u0105da inaczej<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Python ma gotow\u0105 funkcj\u0119, ale podobne podej\u015bcie wyst\u0119puje tak\u017ce w C, C++ i PHP.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"c\">C++<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Tutaj najcz\u0119\u015bciej u\u017cywa si\u0119 reverse iterator\u00f3w kontenera.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>J\u0119zyk<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>C++<\/td><td><code>#include &lt;iostream&gt;<\/code><\/td><\/tr><tr><td>C++<\/td><td><code>#include &lt;vector&gt;<\/code><\/td><\/tr><tr><td>C++<\/td><td><code>using namespace std;<\/code><\/td><\/tr><tr><td>C++<\/td><td><code>int main() {<\/code><\/td><\/tr><tr><td>C++<\/td><td><code>vector&lt;int&gt; v = {1,2,3,4};<\/code><\/td><\/tr><tr><td>C++<\/td><td><code>for(auto it = v.rbegin(); it != v.rend(); ++it)<\/code><\/td><\/tr><tr><td>C++<\/td><td><code>cout &lt;&lt; *it &lt;&lt; \" \";<\/code><\/td><\/tr><tr><td>C++<\/td><td><code>}<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Tutaj <code>rbegin()<\/code> i <code>rend()<\/code> pe\u0142ni\u0105 podobn\u0105 rol\u0119.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"c-1\">C<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">W C nie ma iterator\u00f3w wbudowanych, wi\u0119c stosuje si\u0119 zwyk\u0142\u0105 p\u0119tl\u0119 indeksow\u0105.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>J\u0119zyk<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>C<\/td><td><code>#include &lt;stdio.h&gt;<\/code><\/td><\/tr><tr><td>C<\/td><td><code>int main() {<\/code><\/td><\/tr><tr><td>C<\/td><td><code>int a[] = {1,2,3,4};<\/code><\/td><\/tr><tr><td>C<\/td><td><code>int n = 4;<\/code><\/td><\/tr><tr><td>C<\/td><td><code>for(int i = n - 1; i &gt;= 0; i--)<\/code><\/td><\/tr><tr><td>C<\/td><td><code>printf(\"%d \", a[i]);<\/code><\/td><\/tr><tr><td>C<\/td><td><code>}<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">To rozwi\u0105zanie jest proste i przewidywalne.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"php\">PHP<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">W PHP najcz\u0119\u015bciej u\u017cywa si\u0119 funkcji zwracaj\u0105cej odwr\u00f3con\u0105 tablic\u0119.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>J\u0119zyk<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>PHP<\/td><td><code>&lt;?php<\/code><\/td><\/tr><tr><td>PHP<\/td><td><code>$a = [1,2,3,4];<\/code><\/td><\/tr><tr><td>PHP<\/td><td><code>$b = array_reverse($a);<\/code><\/td><\/tr><tr><td>PHP<\/td><td><code>print_r($b);<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Tutaj zwykle tworzona jest nowa struktura.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"wzory-i-zaleznosci-pamieciowe-przy-pracy-z-iteratorami-oraz-kopiowaniem-danych\">Wzory i zale\u017cno\u015bci pami\u0119ciowe przy pracy z iteratorami oraz kopiowaniem danych<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Przy du\u017cych kolekcjach warto my\u015ble\u0107 nie tylko o poprawno\u015bci, ale te\u017c o koszcie operacji.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Uproszczony model pami\u0119ci:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Zale\u017cno\u015b\u0107<\/th><th>Wz\u00f3r<\/th><\/tr><\/thead><tbody><tr><td>kopia listy<\/td><td><code>O(n)<\/code> pami\u0119ci<\/td><\/tr><tr><td>iterator odwr\u00f3cony<\/td><td><code>O(1)<\/code> pami\u0119ci dodatkowej<\/td><\/tr><tr><td>pe\u0142ne odwr\u00f3cenie przez slicing<\/td><td><code>O(n)<\/code><\/td><\/tr><tr><td>iteracja bez kopiowania<\/td><td><code>O(1)<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Je\u017celi lista ma 10 milion\u00f3w element\u00f3w, r\u00f3\u017cnica przestaje by\u0107 akademicka.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Przy danych liczbowych oznacza to cz\u0119sto setki megabajt\u00f3w dodatkowego u\u017cycia RAM.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">W systemach backendowych, skryptach ETL i analizie log\u00f3w to ma bardzo praktyczne konsekwencje.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"najczestsze-bledy-i-pulapki-ktore-powoduja-niepoprawne-dzialanie-kodu\">Najcz\u0119stsze b\u0142\u0119dy i pu\u0142apki, kt\u00f3re powoduj\u0105 niepoprawne dzia\u0142anie kodu<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"zuzycie-iteratora-tylko-raz\">Zu\u017cycie iteratora tylko raz<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Iterator mo\u017cna przej\u015b\u0107 tylko jeden raz.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Przyk\u0142ad:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>J\u0119zyk<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>Python<\/td><td><code>x = reversed([1,2,3])<\/code><\/td><\/tr><tr><td>Python<\/td><td><code>print(list(x))<\/code><\/td><\/tr><tr><td>Python<\/td><td><code>print(list(x))<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Drugi wynik b\u0119dzie pusty.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To cz\u0119sty b\u0142\u0105d.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"oczekiwanie-zmiany-oryginalnej-listy\">Oczekiwanie zmiany oryginalnej listy<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><code>reversed()<\/code> nie dzia\u0142a jak <code>reverse()<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To trzeba rozr\u00f3\u017cnia\u0107 bardzo \u015bwiadomie.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"proba-uzycia-na-obiekcie-niesekwencyjnym\">Pr\u00f3ba u\u017cycia na obiekcie niesekwencyjnym<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Na przyk\u0142ad zwyk\u0142y generator mo\u017ce nie wsp\u00f3\u0142pracowa\u0107 bez dodatkowej implementacji.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Nie wszystko da si\u0119 odwr\u00f3ci\u0107 bezpo\u015brednio.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"niepotrzebne-kopiowanie-danych\">Niepotrzebne kopiowanie danych<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Wiele os\u00f3b automatycznie pisze <code>[::-1]<\/code>, nawet gdy potrzebna jest tylko iteracja.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To bywa kosztowne i niepotrzebne.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">W kodzie produkcyjnym takie drobiazgi cz\u0119sto s\u0105 \u017ar\u00f3d\u0142em spadku wydajno\u015bci.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"faq\">FAQ<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"czy-reversed-dziala-na-stringach\">Czy <code>reversed()<\/code> dzia\u0142a na stringach?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Tak. Napis jest sekwencj\u0105 znak\u00f3w, wi\u0119c mo\u017cna przej\u015b\u0107 po nim od ko\u0144ca.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>J\u0119zyk<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>Python<\/td><td><code>print(\"\".join(reversed(\"python\")))<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Wynik:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Wynik<\/th><\/tr><\/thead><tbody><tr><td><code>nohtyp<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"czy-reversed-dziala-na-slownikach\">Czy <code>reversed()<\/code> dzia\u0142a na s\u0142ownikach?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Nie bezpo\u015brednio w klasycznym sensie dla wszystkich przypadk\u00f3w. Najcz\u0119\u015bciej trzeba najpierw pobra\u0107 list\u0119 kluczy lub element\u00f3w.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"czy-reverse-jest-szybsze-niz-reversed\">Czy <code>reverse()<\/code> jest szybsze ni\u017c <code>reversed()<\/code>?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">To zale\u017cy od celu. Je\u015bli trzeba zmieni\u0107 list\u0119 na sta\u0142e \u2014 zwykle tak. Je\u015bli potrzebna jest tylko iteracja od ko\u0144ca \u2014 iterator jest lepszym wyborem.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"czy-mozna-uzywac-tego-w-petli-for-bez-list\">Czy mo\u017cna u\u017cywa\u0107 tego w p\u0119tli <code>for<\/code> bez <code>list()<\/code>?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Tak, i w\u0142a\u015bnie wtedy ma to najwi\u0119kszy sens.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>J\u0119zyk<\/th><th>Kod<\/th><\/tr><\/thead><tbody><tr><td>Python<\/td><td><code>for x in reversed(lista):<\/code><\/td><\/tr><tr><td>Python<\/td><td><code>print(x)<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"czy-slicing-1-jest-bledem\">Czy slicing <code>[::-1]<\/code> jest b\u0142\u0119dem?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Nie, ale tworzy kopi\u0119 danych. Dla ma\u0142ych list nie ma to zwykle znaczenia, dla du\u017cych ju\u017c tak.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Iterator odwr\u00f3cony jest prostym narz\u0119dziem, ale dobrze pokazuje r\u00f3\u017cnic\u0119 mi\u0119dzy \u201emie\u0107 wynik\u201d a \u201emie\u0107 wynik bez niepotrzebnego kosztu\u201d. W nauce programowania takie szczeg\u00f3\u0142y wygl\u0105daj\u0105 niepozornie, a p\u00f3\u017aniej w\u0142a\u015bnie one decyduj\u0105 o tym, czy kod jest tylko poprawny, czy naprawd\u0119 dobry.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>\u0179r\u00f3d\u0142o Foto: Freepik<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Praca z kolekcjami danych bardzo cz\u0119sto ko\u0144czy si\u0119 nie na ich odczycie, ale na potrzebie przej\u015bcia po elementach w odwrotnej kolejno\u015bci. Dotyczy to list, tablic, ci\u0105g\u00f3w znak\u00f3w, wynik\u00f3w oblicze\u0144 i struktur u\u017cywanych w algorytmach. Odwracanie kolejno\u015bci nie zawsze oznacza fizyczn\u0105 zmian\u0119 danych w pami\u0119ci &#8211; cz\u0119sto wystarczy iterator, kt\u00f3ry pozwala przej\u015b\u0107 po elementach od ko\u0144ca do pocz\u0105tku bez kopiowania ca\u0142ej struktury. W Pythonie w\u0142a\u015bnie do tego s\u0142u\u017cy Reversed \u2013 zwraca odwr\u00f3cony iterator. Reversed \u2013 zwraca odwr\u00f3cony iterator i pozwala przechodzi\u0107 po danych bez kopiowania ca\u0142ej struktury Funkcja reversed() w Pythonie zwraca iterator dzia\u0142aj\u0105cy od ko\u0144ca kolekcji do pocz\u0105tku. To wa\u017cne rozr\u00f3\u017cnienie &#8211; nie zwraca nowej listy, tylko obiekt iteratora, kt\u00f3ry kolejno udost\u0119pnia elementy w odwrotnej kolejno\u015bci. To oznacza dwie praktyczne rzeczy: Dla ma\u0142ych danych r\u00f3\u017cnica bywa niewielka, ale przy listach licz\u0105cych setki tysi\u0119cy lub miliony element\u00f3w ma to ju\u017c realne znaczenie. Najprostsza sk\u0142adnia wygl\u0105da tak: Operacja Kod Python wynik = reversed(lista) Je\u017celi chcemy zobaczy\u0107 wynik jako list\u0119, trzeba jawnie go zamieni\u0107: Operacja Kod Python print(list(reversed([1, 2, 3, 4]))) Wynik: Wej\u015bcie Wynik [1, 2, 3, 4] [4, 3, 2, 1] To zachowanie r\u00f3\u017cni si\u0119 od metod, kt\u00f3re faktycznie modyfikuj\u0105 dane, np. list.reverse(). W praktyce bardzo cz\u0119sto spotyka si\u0119 b\u0142\u0105d pocz\u0105tkuj\u0105cych: kto\u015b oczekuje, \u017ce reversed() zmieni oryginaln\u0105 list\u0119. Nie zmieni. Zwraca tylko iterator. Przyk\u0142ad: J\u0119zyk Kod Python a = [10, 20, 30] Python b = reversed(a) Python print(a) Wynik nadal b\u0119dzie: Wynik [10, 20, 30] Oryginalna struktura pozostaje bez zmian. R\u00f3\u017cnica mi\u0119dzy reversed(), reverse() oraz odwracaniem przez indeksowanie ma znaczenie wydajno\u015bciowe W praktyce istniej\u0105 trzy najcz\u0119\u015bciej u\u017cywane sposoby pracy z odwr\u00f3con\u0105 kolejno\u015bci\u0105: Na pierwszy rzut oka wygl\u0105daj\u0105 podobnie, ale dzia\u0142aj\u0105 inaczej. reversed() Zwraca iterator. Nie modyfikuje oryginalnej listy. Dobre rozwi\u0105zanie, gdy trzeba tylko przej\u015b\u0107 po danych od ko\u0144ca. list.reverse() To metoda listy. Modyfikuje list\u0119 \u201ew miejscu\u201d, czyli bez tworzenia nowego obiektu. Po wykonaniu tej operacji oryginalna kolejno\u015b\u0107 zostaje utracona. slicing [::-1] Tworzy now\u0105 kopi\u0119 listy w odwrotnej kolejno\u015bci. Wygodne, ale przy du\u017cych danych koszt pami\u0119ci mo\u017ce by\u0107 istotny. Por\u00f3wnanie: Metoda Modyfikuje orygina\u0142 Tworzy kopi\u0119 Zwraca iterator reversed() nie nie tak reverse() tak nie nie [::-1] nie tak nie Przyk\u0142ad: J\u0119zyk Kod Python a = [1,2,3,4] Python b = a[::-1] Python a.reverse() Po tej operacji: Zmienna Warto\u015b\u0107 a [4,3,2,1] b [4,3,2,1] R\u00f3\u017cnica jest taka, \u017ce b jest now\u0105 list\u0105, a a zosta\u0142a zmieniona. W systemach przetwarzaj\u0105cych du\u017ce dane to nie jest detal. Kopiowanie milionowych struktur potrafi kosztowa\u0107 sekundy czasu i setki MB RAM. Reversed \u2013 zwraca odwr\u00f3cony iterator w obiektach w\u0142asnych tylko wtedy, gdy spe\u0142nione s\u0105 warunki protoko\u0142u iteracji Nie ka\u017cda struktura mo\u017ce zosta\u0107 u\u017cyta z reversed() automatycznie. Python wymaga spe\u0142nienia jednego z dw\u00f3ch warunk\u00f3w: To wa\u017cne przy pisaniu w\u0142asnych struktur danych. Przyk\u0142ad w\u0142asnego obiektu: J\u0119zyk Kod Python class Dane: Python def __init__(self): Python self.x = [10, 20, 30] Python def __len__(self): Python return len(self.x) Python def __getitem__(self, i): Python return self.x[i] Teraz: J\u0119zyk Kod Python for i in reversed(Dane()): Python print(i) zadzia\u0142a poprawnie. Bez tego pojawi si\u0119 wyj\u0105tek TypeError. W projektach produkcyjnych taki problem pojawia si\u0119 cz\u0119sto przy w\u0142asnych kontenerach, wrapperach bazodanowych albo strukturach pomocniczych w bibliotekach. Warto pami\u0119ta\u0107: iterator odwr\u00f3cony nie jest \u201emagiczny\u201d, Python musi wiedzie\u0107, jak dosta\u0107 si\u0119 do ostatniego elementu i jak przechodzi\u0107 wstecz. Zastosowanie w algorytmach, stosach, parsowaniu i analizie danych sekwencyjnych Odwr\u00f3cona iteracja jest bardzo praktyczna i nie jest tylko ciekawostk\u0105 sk\u0142adni. Przechodzenie po stosie Struktura stosu dzia\u0142a zgodnie z zasad\u0105 LIFO &#8211; ostatni wszed\u0142, pierwszy wyszed\u0142. Cz\u0119sto chcemy przejrze\u0107 histori\u0119 operacji od najnowszej do najstarszej. J\u0119zyk Kod Python operacje = [&#8222;logowanie&#8221;, &#8222;edycja&#8221;, &#8222;zapis&#8221;, &#8222;wylogowanie&#8221;] Python for x in reversed(operacje): Python print(x) To jest naturalny przypadek u\u017cycia. Analiza tekstu od ko\u0144ca Parsery, kompilatory i walidatory sk\u0142adni czasem analizuj\u0105 dane od ko\u0144ca, np. przy sprawdzaniu nawias\u00f3w lub ko\u0144c\u00f3wek sk\u0142adniowych. Przyk\u0142ad: J\u0119zyk Kod Python tekst = &#8222;raport_final_v2.txt&#8221; Python for znak in reversed(tekst): Python print(znak) Dzi\u0119ki temu mo\u017cna szybciej szuka\u0107 rozszerzenia pliku lub sufiksu. Dynamic programming i tablice pomocnicze Niekt\u00f3re algorytmy wymagaj\u0105 przechodzenia od ko\u0144ca, \u017ceby nie nadpisywa\u0107 potrzebnych jeszcze danych. Typowy przyk\u0142ad to problem plecakowy lub obliczenia na prefiksach i sufiksach. Schemat: Zastosowanie Kierunek iteracji prefiksy od pocz\u0105tku sufiksy od ko\u0144ca DP 1D cz\u0119sto od ko\u0144ca stos operacji od ko\u0144ca Tu iterator odwr\u00f3cony jest bardzo wygodny i bezpieczny. Reversed \u2013 zwraca odwr\u00f3cony iterator r\u00f3wnie\u017c w innych j\u0119zykach, cho\u0107 mechanizm wygl\u0105da inaczej Python ma gotow\u0105 funkcj\u0119, ale podobne podej\u015bcie wyst\u0119puje tak\u017ce w C, C++ i PHP. C++ Tutaj najcz\u0119\u015bciej u\u017cywa si\u0119 reverse iterator\u00f3w kontenera. J\u0119zyk Kod C++ #include &lt;iostream&gt; C++ #include &lt;vector&gt; C++ using namespace std; C++ int main() { C++ vector&lt;int&gt; v = {1,2,3,4}; C++ for(auto it = v.rbegin(); it != v.rend(); ++it) C++ cout &lt;&lt; *it &lt;&lt; &#8221; &#8222;; C++ } Tutaj rbegin() i rend() pe\u0142ni\u0105 podobn\u0105 rol\u0119. C W C nie ma iterator\u00f3w wbudowanych, wi\u0119c stosuje si\u0119 zwyk\u0142\u0105 p\u0119tl\u0119 indeksow\u0105. J\u0119zyk Kod C #include &lt;stdio.h&gt; C int main() { C int a[] = {1,2,3,4}; C int n = 4; C for(int i = n &#8211; 1; i &gt;= 0; i&#8211;) C printf(&#8222;%d &#8222;, a[i]); C } To rozwi\u0105zanie jest proste i przewidywalne. PHP W PHP najcz\u0119\u015bciej u\u017cywa si\u0119 funkcji zwracaj\u0105cej odwr\u00f3con\u0105 tablic\u0119. J\u0119zyk Kod PHP &lt;?php PHP $a = [1,2,3,4]; PHP $b = array_reverse($a); PHP print_r($b); Tutaj zwykle tworzona jest nowa struktura. Wzory i zale\u017cno\u015bci pami\u0119ciowe przy pracy z iteratorami oraz kopiowaniem danych Przy du\u017cych kolekcjach warto my\u015ble\u0107 nie tylko o poprawno\u015bci, ale te\u017c o koszcie operacji. Uproszczony model pami\u0119ci: Zale\u017cno\u015b\u0107 Wz\u00f3r kopia listy O(n) pami\u0119ci iterator odwr\u00f3cony O(1) pami\u0119ci dodatkowej pe\u0142ne odwr\u00f3cenie przez slicing O(n) iteracja bez kopiowania O(1) Je\u017celi lista ma 10 milion\u00f3w element\u00f3w, r\u00f3\u017cnica przestaje by\u0107 akademicka. Przy danych liczbowych oznacza to cz\u0119sto setki megabajt\u00f3w dodatkowego u\u017cycia RAM. W systemach backendowych, skryptach ETL i analizie log\u00f3w to ma bardzo praktyczne konsekwencje. Najcz\u0119stsze b\u0142\u0119dy i pu\u0142apki, kt\u00f3re powoduj\u0105 niepoprawne dzia\u0142anie kodu Zu\u017cycie iteratora tylko raz Iterator mo\u017cna przej\u015b\u0107 tylko jeden raz. Przyk\u0142ad: J\u0119zyk Kod Python x = reversed([1,2,3]) Python print(list(x)) Python print(list(x)) Drugi wynik b\u0119dzie pusty. To cz\u0119sty b\u0142\u0105d. Oczekiwanie zmiany oryginalnej listy reversed() nie dzia\u0142a jak reverse(). To trzeba rozr\u00f3\u017cnia\u0107 bardzo \u015bwiadomie. Pr\u00f3ba u\u017cycia na obiekcie niesekwencyjnym Na przyk\u0142ad zwyk\u0142y generator mo\u017ce nie wsp\u00f3\u0142pracowa\u0107 bez dodatkowej implementacji. Nie wszystko da si\u0119 odwr\u00f3ci\u0107 bezpo\u015brednio. Niepotrzebne kopiowanie danych Wiele os\u00f3b automatycznie pisze [::-1], nawet gdy potrzebna jest tylko iteracja. To bywa kosztowne i niepotrzebne. W kodzie produkcyjnym takie drobiazgi cz\u0119sto s\u0105 \u017ar\u00f3d\u0142em spadku wydajno\u015bci. FAQ Czy reversed() dzia\u0142a na stringach? Tak. Napis jest sekwencj\u0105 znak\u00f3w, wi\u0119c mo\u017cna przej\u015b\u0107 po nim od ko\u0144ca. J\u0119zyk Kod Python print(&#8222;&#8221;.join(reversed(&#8222;python&#8221;))) Wynik: Wynik nohtyp Czy reversed() dzia\u0142a na s\u0142ownikach? Nie bezpo\u015brednio w klasycznym sensie dla wszystkich przypadk\u00f3w. Najcz\u0119\u015bciej trzeba najpierw pobra\u0107 list\u0119 kluczy lub element\u00f3w. Czy reverse() jest szybsze ni\u017c reversed()? To zale\u017cy od celu. Je\u015bli trzeba zmieni\u0107 list\u0119 na sta\u0142e \u2014 zwykle tak. Je\u015bli potrzebna jest tylko iteracja od ko\u0144ca \u2014 iterator jest lepszym wyborem. Czy mo\u017cna u\u017cywa\u0107 tego w p\u0119tli for bez list()? Tak, i w\u0142a\u015bnie wtedy ma to najwi\u0119kszy sens. J\u0119zyk Kod Python for x in reversed(lista): Python print(x) Czy slicing [::-1] jest b\u0142\u0119dem? Nie, ale tworzy kopi\u0119 danych. Dla ma\u0142ych list nie ma to zwykle znaczenia, dla du\u017cych ju\u017c tak. Iterator odwr\u00f3cony jest prostym narz\u0119dziem, ale dobrze pokazuje r\u00f3\u017cnic\u0119 mi\u0119dzy \u201emie\u0107 wynik\u201d a \u201emie\u0107 wynik bez niepotrzebnego kosztu\u201d. W nauce programowania takie szczeg\u00f3\u0142y wygl\u0105daj\u0105 niepozornie, a p\u00f3\u017aniej w\u0142a\u015bnie one decyduj\u0105 o tym, czy kod jest tylko poprawny, czy naprawd\u0119 dobry. \u0179r\u00f3d\u0142o Foto: Freepik<\/p>\n","protected":false},"author":1,"featured_media":1529,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[27],"tags":[],"class_list":["post-1528","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-jezyk-programowania"],"_links":{"self":[{"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/posts\/1528","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/comments?post=1528"}],"version-history":[{"count":1,"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/posts\/1528\/revisions"}],"predecessor-version":[{"id":1530,"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/posts\/1528\/revisions\/1530"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/media\/1529"}],"wp:attachment":[{"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/media?parent=1528"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/categories?post=1528"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/trzykody.pl\/index.php\/wp-json\/wp\/v2\/tags?post=1528"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}