2016-02-12 12 views
12

W małym skrypcie, który napisałem, funkcja .append() dodaje wprowadzony element na początku listy, zamiast na końcu tej listy. (Jak można jasno zrozumieć, jestem zupełnie nowy w Pythonie, więc iść łatwo na mnie)Kolejność list w pythonach

list.append(x)
Dodaj element na końcu listy; odpowiednik a[len(a):] = [x].

Tak mówi się w https://docs.python.org/2/tutorial/datastructures.html.

Można zobaczyć mój poniższy kod:

user_input = [] 
def getting_text(entered_text): 
    if entered_text == "done": 
     print "entering the texts are done!" 
    else: 
     getting_text(raw_input("Enter the text or write done to finish entering ")) 
     user_input.append(entered_text) 

getting_text(raw_input("Enter the first text ")) 
print user_input 

jestem nieporozumienie coś tutaj, ponieważ drukuje Funkcja drukowania c,b,a zamiast a,b,c (kolejność wszedłem wejście jest a,b,c)

+2

FWIW za pomocą rekursji w Pythonie rzadko jest dobrym pomysłem, chyba że przetwarzanie rekurencyjne struktury danych (np. drzewo), ponieważ Python ogranicza głębokość rekursywnych wywołań i nie może wyeliminować [ogona połączenia] (https://en.wikipedia.org/wiki/Tail_call). –

+5

Jeśli jesteś nowym użytkownikiem Pythona ... dlaczego używasz python2.7, który jest "wersją 5+ lat"? Po prostu poznaj python3 teraz, a ostatecznie, jeśli Oyu potrzebuje obsługi starszych systemów, poznasz różnice z python2. – Bakuriu

+0

Najlepszym narzędziem online (zdecydowanym po zapytaniu kilku znajomych) była Codecademy, która używa 2.7. Dodatkowo powiedziano mi, że nie ma zbyt wielu różnic i mogę łatwo przejść na 3.x. Zapisałem się również na niektóre kursy 3.x, takie jak w Udemy, ale jeszcze się nie rozpoczęły. Prawdopodobnie przerzucę się na 3.x, kiedy będę czuć się komfortowo :) – firko

Odpowiedz

28

Ok, to co się dzieje.

Kiedy twój tekst nie jest "done", zaprogramowałeś go tak, aby od razu wywołać tę funkcję (tzn. Wywołać ją rekurencyjnie). Zwróć uwagę, jak to ustawiłeś, aby dodać element do listy PO wykonaniu linii getting_text(raw_input("Enter the text or write done to finish entering ")).

Tak więc, po dodaniu zmiennych, dodamy wszystkie zmienne PO zakończeniu funkcji rekursywnej.

W związku z tym, po wpisaniu a, ponownie wywołuje funkcję (jeszcze nic nie wprowadziła do listy). Następnie wpisz: b, a następnie c. Po wpisaniu done bit rekurencyjny zostanie zakończony. TERAZ, robi to user_input.append(.... JEDNAKŻE zamówienie jest odwrócone, ponieważ dotyczy ono najpierw c, ponieważ była to ostatnia rzecz.

To może być pokazany podczas drukowania listy wewnątrz funkcji:

>>> def getting_text(entered_text): 
...  print user_input 
...  if entered_text == "done": 
...   print "entering the texts are done!" 
...  else: 
...    getting_text(raw_input("Enter the text or write done to finish entering ")) 
...    user_input.append(entered_text) 
... 
>>> 
>>> getting_text(raw_input("Enter the first text ")) 
Enter the first text a 
[] 
Enter the text or write done to finish entering b 
[] 
Enter the text or write done to finish entering c 
[] 
Enter the text or write done to finish entering done 
[] 
entering the texts are done! 
>>> user_input 
['c', 'b', 'a'] 

Uwaga oświadczenie linia wydruku 2.


Więc jak można rozwiązać ten problem? Proste: dołącz do listy przed wywołaniem rekursywnym.

>>> user_input = [] 
>>> def getting_text(entered_text): 
...  if entered_text == "done": 
...   print "entering the texts are done!" 
...  else: 
...    user_input.append(entered_text) 
...    getting_text(raw_input("Enter the text or write done to finish entering ")) 
... 
>>> user_input = [] 
>>> getting_text(raw_input("Enter the first text ")) 
Enter the first text a 
Enter the text or write done to finish entering b 
Enter the text or write done to finish entering c 
Enter the text or write done to finish entering done 
entering the texts are done! 
>>> user_input 
['a', 'b', 'c'] 
+0

Rzeczywiście, obłudne i czyste wyjaśnienie. Dziękuję Ci.! –

4

Twój rekurencyjna funkcja getting_text nazywa się przed dodaniem entered_text do listy. Tak więc efekt połączeń wewnętrznych poprzedza efekt połączeń zewnętrznych.

Jeśli zamienić wokół

getting_text(raw_input("Enter the text or write done to finish entering ")) 
user_input.append(entered_text) 

do

user_input.append(entered_text) 
getting_text(raw_input("Enter the text or write done to finish entering ")) 

następnie zawartość user_input będzie w odwrotnej kolejności.

5

Masz rekursję w swoim skrypcie. Skrypt przechodzi do getting_text przed dołączeniem do listy. Tak więc dołączenie jest wykonywane, gdy funkcja rekurencji w końcu powraca.W ten sposób kierujesz stos w dół na ścieżce powrotnej wykonując wywołanie append() oczekując na wykonanie w odwrotnej kolejności.

Może łatwiej jest unterstand tak:

getting_text() 
    getting_text() 
     getting_text() 
     append() 
    append() 
append() 

Jeśli chcesz mieć wynik w „prawidłowym” aby przesunąć append on line, przed wywołaniem getting_text().

3

Kolejność jest wstecznie powodu recursiveness z getting_text, powinien działać zgodnie z oczekiwaniami, jeśli dołączy entered_text przed wywołanie rekurencyjne lub użyj iteracyjny funkcję jak ten

user_input = [] 
def getting_text(entered_text): 
    while (entered_text != 'done'): 
     user_input.append(entered_text) 
     entered_text = raw_input("Enter the text or write done to finish entering ") 
    print "entering the texts are done!" 
getting_text(raw_input("Enter the first text ")) 
print user_input 
+0

Cóż, możliwe jest uzyskanie pożądanej kolejności przez wykonanie przedrostka przed wywołaniem rekursywnym (jak pokazują niektóre inne odpowiedzi). Ale oczywiście zgadzam się, że zamiast rekursji lepiej jest użyć prostej pętli 'while'. –

+0

który również jest poprawny, dzięki za pomoc – firko

3

robisz rzęsiste rekurencyjnych rzeczy tutaj: Wywołujecie funkcję:

getting_text(entered_text) 

z wewnątrz siebie. Nie jestem pewna, tego właśnie chcesz.

Stworzyłem pewną rzecz, która jest zbyt brzydki, ale robi to, co chcesz - myślę ..

import sys 

user_input = [] 
def getting_text(entered_text): 
    if entered_text == "done": 
     print user_input 
     sys.exit(0) 
    else: 
     user_input.append(entered_text) 

while(1): 
    getting_text(raw_input("Enter the text or write done to finish entering: "))  
+1

Wywołanie 'sys.exit()' wewnątrz funkcji jest trochę drastyczne. Dlaczego nie po prostu zwrócić "True", gdy wprowadzono zwykły tekst i 'False', gdy wprowadzono" done ". BTW, kiedy musisz wyjść, jest prostszy sposób niż 'sys.exit()': możesz po prostu zrobić 'exit()'. –

+0

tak, robi dokładnie to, co chcę – firko

+0

PM 2 Ring: Masz rację ... –