Dzisiejsze zadanie to już chyba klasyk rozmów kwalifikacyjnych. Zobacz jak łatwo można je rozwiązać.

Napisz kod, który dla zadanego ciągu tekstowego : tekst = 'Jeśli wszyscy myślą tak samo, to ktoś nie myśli wcale' odwróci kolejność liter we wszystkich słowach w tym tekście. Zatem tekst po zamianie będzie wyglądało następująco: "ilśeJ ycsyzsw ąlśym kat ,omas ot śotk ein ilśym elacw".

Najczęstsze błędy

Wielu kandydatów tworzy skomplikowane rozwiązania, które w wielu liniach modyfikują zadany tekst. Tymczasem zadanie to można rozwiązać w jednej linii kodu. Bardzo chciałem pokazać wam przykład złego rozwiązanie, jednak z przykrością stwierdzam, że nie jestem w stanie. Nie umiem i koniec. Dlatego od razu zajmiemy się poprawnym kodem i dokładnie go sobie omówimy.

Rozwiązanie

 

tekst = 'Jeśli wszyscy myślą tak samo, to ktoś nie myśli wcale'

tekst_odwrocony = ' '.join(slowo[::-1] for slowo in tekst.split())

print(tekst_odwrocony)

Uruchom w edytorze

Nic się nie martw jeśli nie do końca rozumiesz co tu się stało i dlaczego to działa. Zaraz krok po kroku przejdziemy przez wszystkie funkcje i kruczki użyte w tym rozwiązaniu.

Metoda split

Jest to metoda klasy str, umożliwiająca podział ciągu tekstowego na części, które zwracane są w postaci listy. Jako parametr przyjmuje znak po którym ma nastąpić podział. Zatem nasze wywołanie metody split() powinno wyglądać następująco: tekst.split(' ')by podzielić nasz tekst po „spacjach”. Jak pewnie zauważyłeś w naszym rozwiązaniu wywołaliśmy metodę split bez żadnych parametrów. To dlatego, że „spacja” (biały znak) jest parametrem domyślnym. Zatem dzięki metodzie split mamy już listę zawierającą wszystkie słowa z naszego tekstu. To krótki przykład jak działa split:

tekst = 'Jeśli wszyscy myślą tak samo, to ktoś nie myśli wcale'

lista_slow = tekst.split()
print(lista_slow)

Uruchom w edytorze

Output:

['Jeśli', 'wszyscy', 'myślą', 'tak', 'samo,', 'to', 'ktoś', 'nie', 'myśli', 'wcale']

Odwracanie liter w wyrazie

Jak już uda nam dostać się do konkretnego słowa zapisanego w naszej liście trzeba odwrócić w nim litery. Robimy to za pomocą operatora zakresu. Operator ten może przyjąć trzy wartości [indeks początkowy : indeks końcowy : skok]. My używamy go tak : slowo[::-1]. Zatem czytamy go następująco. Od początku wyrazu do jego samego końca ze skokiem o wartości -1. To właśnie skok -1 robi tu robotę. Oznacza to że idziemy od końca wyrazu do jego początku, a zatem odwracamy kolejność liter.

slowo = 'wszyscy'
slowo_odwrocone = slowo[::-1]
print(slowo_odwrocone)

Uruchom w edytorze

Output:

ycsyzsw

Generator składny

Wiemy już jak podzielić tekst na listę zawierającą poszczególne słowa. Wiemy też jak odwrócić kolejność liter w danym słowie. Jak przeprowadzić tą operację na każdym słowie będącym w naszej liście ? Odpowiedź jest prosta. Generator składany. Oczywiście można by tu posłużyć się zwykłą lista składna i efekt końcowy byłby taki sam. Użycie generatora jest jednak dużo schludniejszym rozwiązaniem oszczędzającym naszą pamięć.

tekst = 'Jeśli wszyscy myślą tak samo, to ktoś nie myśli wcale'

generator_odwracający = (slowo[::-1] for slowo in tekst.split(' '))

print(type(generator_odwracający))

for odwrcone_slowo in generator_odwracający:
  print(odwrcone_slowo)

Uruchom w edytorze

Output:

<class 'generator'>
ilśeJ
ycsyzsw
ąlśym
kat
,omas
ot
śotk
ein
ilśym
elacw

Metoda join

Metoda join (również metoda klasy str) jest przeciwieństwem omawianej wcześniej metody split. Metoda split z ciągu tekstowego tworzy listę. Natomiast metoda join wywoływana na rzecz ciągu tekstowego pobiera listę (lubi inną kolekcję) i robi z niej ciąg tekstowy. Najłatwiej zobrazuje to przykład:

tekst = ['Python' ,'jest' ,'fajny']

print('XX'.join(tekst))
print(' '.join(tekst))

Output:

PythonXXjestXXfajny
Python jest fajny

Jak widzisz ”string” na rzecz którego wywoła zostanie metoda join staje się separatorem. W naszym przykładzie separatorem zostanie znak spacji.

Jeszcze jedna ważna rzecz

Wprawni obserwatorzy na pewno zauważą, że w naszym wywołaniu metody join brakuje nawiasów należących do generatora składanego.

Powinno być:

tekst_odwrocony = ' '.join((slowo[::-1] for slowo in tekst.split(' ')))

Tymczasem mamy:

tekst_odwrocony = ' '.join(slowo[::-1] for slowo in tekst.split(' '))

Oba rozwiązania działają ,a nawet są sobie równoważne. Jest to kolejne udogodnienie języka Python. Jeśli mamy zamiar przekazać generator składany bezpośrednio w wywołaniu funkcji nawiasy te nie są wymagane. Ma to na celu uproszczenie zapisu.