2010-12-22 8 views
2

Ich bin eine Übung wie folgt:Unterschied zwischen 2 Stück Python-Code

# B. front_x 
# Given a list of strings, return a list with the strings 
# in sorted order, except group all the strings that begin with 'x' first. 
# e.g. ['mix', 'xyz', 'apple', 'xanadu', 'aardvark'] yields 
# ['xanadu', 'xyz', 'aardvark', 'apple', 'mix'] 
# Hint: this can be done by making 2 lists and sorting each of them 
# before combining them. 

Probenlösung:

def front_x(words): 
    listX = [] 
    listO = [] 

    for w in words: 
    if w.startswith('x'): 
     listX.append(w) 
    else: 
     listO.append(w) 

    listX.sort() 
    listO.sort() 

    return listX + listO 

meine Lösung:

def front_x(words): 
    listX = [] 

    for w in words: 
    if w.startswith('x'): 
     listX.append(w) 
     words.remove(w) 

    listX.sort() 
    words.sort() 

    return listX + words 

wie ich meine Lösung getestet Das Ergebnis ist ein bisschen komisch. Hier ist der Quellcode mit meiner Lösung: http://dl.dropbox.com/u/559353/list1.py. Vielleicht möchten Sie es ausprobieren.

+2

Haben Sie eine spezielle Frage, außer "Was ist falsch mit meinem Code"? – Bobby

+0

-1: "Das Ergebnis ist ein bisschen komisch". Vage und schwer zu beantworten. Bitte geben Sie etwas Spezifisches an, das Sie reparieren möchten. –

Antwort

3

Das Problem ist, dass Sie eine Schleife über die Liste und entfernen Sie Elemente aus ihr (es zu ändern):

for w in words: 
    if w.startswith('x'): 
     listX.append(w) 
     words.remove(w) 

Beispiel:

>>> a = range(5) 
>>> for i in a: 
... a.remove(i) 
... 
>>> a 
[1, 3] 

Dieser Code funktioniert wie folgt:

  • Holen Sie sich das erste Element, entfernen Sie es.
  • Zum nächsten Element wechseln. Aber es ist nicht mehr 1, weil wir zuvor 0 entfernt und damit 1 das neue erste Element geworden sind. Das nächste Element ist daher 2 und 1 wird übersprungen.
  • Gleiches für 3 und 4.
+0

Ja, ich verstehe. In Ihrem Beispiel wird 1 nach dem Entfernen von 0 aus a zum 0. Element und wird in der nächsten Schleife übersprungen. – draw

0

Das Ändern der Liste, über die Sie iterieren, führt zu undefiniertem Verhalten. Aus diesem Grund erstellt die Beispiellösung zwei neue Listen, anstatt sie aus der Quellenliste zu löschen.

for w in words: 
    if w.startswith('x'): 
    listX.append(w) 
    words.remove(w) # Problem here! 

Eine Diskussion zu diesem Thema finden Sie unter this question. Es läuft im Grunde darauf hinaus, Iteratoren aufzulisten, die durch die Indizes der Liste iterieren, ohne zurückzugehen und nach Modifikationen zu suchen (was teuer wäre!).

Wenn Sie die Erstellung einer zweiten Liste vermeiden möchten, müssen Sie zwei Iterationen durchführen. Eins, um über words zu iterieren, um listX zu erstellen, und ein anderes, um über listX zu iterieren, das von words löscht.

1

zwei wesentliche Unterschiede:

  1. ein Element aus einer Liste Looping entfernen, wo die Liste iteriert wird funktioniert nicht ganz in Python. Wenn Sie Java verwenden, erhalten Sie eine Ausnahme, die besagt, dass Sie eine Sammlung ändern, die iteriert wird. Python ruft diesen Fehler anscheinend nicht auf. @Felix_Kling erklärt es recht gut in seiner Antwort.
  2. Sie ändern auch den Eingangsparameter words. So wird der Aufrufer Ihrer Funktion front_x nach der Ausführung der Funktion words geändert sehen. Dieses Verhalten ist, sofern nicht explizit erwartet, besser zu vermeiden. Stellen Sie sich vor, Ihr Programm macht etwas anderes mit words. Zwei Listen wie in der sample solution zu halten ist ein besserer Ansatz.
0

Das ist irreführend und unnötig andeuten, können Sie dies tun, ohne die Sortierung und die Kombination von zwei Listen unabhängig:

>>> items = ['mix', 'xyz', 'apple', 'xanadu', 'aardvark'] 
>>> sorted(items, key=lambda item: (item[0]!='x', item)) 
['xanadu', 'xyz', 'aardvark', 'apple', 'mix'] 

Der eingebaute in sortierter() Funktion, um eine Optionstaste Argument, der ihm sagt, was zu sortiere nach. In diesem Fall möchten Sie Tupel wie (False, 'xanadu') oder (True, 'apple') für jedes Element der ursprünglichen Liste erstellen, was Sie mit einem Lambda tun können.

Verwandte Themen