B. front_x Geben Sie bei einer Liste von Zeichenfolgen eine Liste mit den Zeichenfolgen in sortierter Reihenfolge zurück, mit der Ausnahme, dass alle Zeichenfolgen gruppiert werden, die zuerst mit 'x' beginnen. z.B. ['mix', 'xyz', 'apple', 'xanadu', 'aardvark'] ergibt ['xanadu', 'xyz', 'aardvark', 'apple', 'mix'] Hinweis: Dies kann durch erfolgen Erstellen Sie zwei Listen und sortieren Sie jede, bevor Sie sie kombinieren.

def front_x(words):
  xList = []
  nonXList = []
  for word in words:
    if word[0] == 'x':
      xList.append(word)
    else:
      nonXList.append(word)
  return sorted(xList) + sorted(nonXList)

Ich bin neu in Python und Programmierung im Allgemeinen, aber ich denke, es gibt eine kompaktere Möglichkeit, diesen Code zu schreiben, oder gibt es eine "pythonischere" Methode?

Auch ich habe versucht, die Zeile zurückzugeben:

return xlist.sort() + nonXList.sort()

Aber das hat sich geirrt. Warum ist das passiert?

1
user2093601 6 Dez. 2013 im 23:52

7 Antworten

Beste Antwort

Sie können words mit einem Aufruf von sorted mithilfe des Parameters key sortieren, um sorted zu "lehren", wie die Artikel in words bestellt werden sollen:

def front_x(words):
    return sorted(words, key=lambda word: (word[0] != 'x', word))

Die Funktion key wird für jedes Element in words einmal aufgerufen und gibt einen Proxy-Wert zurück, nach dem die Elemente in words sortiert werden sollen. tuples wie die von der obigen Funktion lambda zurückgegebene werden in lexikografischer Reihenfolge sortiert (nach dem ersten Element im Tupel und nach dem zweiten, um die Verbindung zu lösen).

Diese und andere Techniken werden im ausgezeichneten Sorting Howto erläutert.


Beispielsweise,

print(front_x(['mix', 'xyz', 'apple', 'xanadu', 'aardvark']))
# ['xanadu', 'xyz', 'aardvark', 'apple', 'mix']

Beachten Sie, dass word[0] eine IndexError auslöst, wenn words eine leere Zeichenfolge enthält. Im Gegensatz dazu gibt ''.startswith('x') False zurück. Verwenden Sie also word.startswith('x'), wenn front_x leere Zeichenfolgen verarbeiten soll, und word[0] == 'x', wenn Sie eine Ausnahme auslösen möchten.

5
unutbu 6 Dez. 2013 im 20:16

Der Fehler bei Ihrer Rückgabe besteht darin, dass sort keinen Wert zurückgibt, sondern lediglich die Liste ändert.

Dies scheint ein ziemlich schneller Weg zu sein, es läuft in linearer Zeit, Sie werden nicht viel schneller als das. Davon abgesehen könnten Sie Inline-Code verwenden, um ihn zu verkürzen, aber auf diese Weise ist er nicht immer besser lesbar.

1
Dylan Lawrence 6 Dez. 2013 im 19:54

Der Fehler liegt daran, dass .sort() vorhanden ist. Es gibt None zurück und Sie können None + None nicht ausführen

Da Pythons Sortierung stabil ist, können Sie dies auch durch zwei Sortierungen erreichen

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

Und die In-Place-Version

>>> L.sort()
>>> L.sort(key=lambda x:x[0]!='x')
>>> L
['xanadu', 'xyz', 'aardvark', 'apple', 'mix']
0
John La Rooy 6 Dez. 2013 im 20:14

Dies funktioniert und ist einfach und leicht zu verstehen.

def front_x(words):
    xlist = [item for item in words if item[0] =='x']
    nonXList = [item for item in words if item[0] !='x']
    xlist.sort() # The .sort() method sorts a list alphabetically 
    nonXList.sort()
    Combined_Lists = xlist + nonXList
    return Combined_Lists
    #You can also comment Combined_Lists and 
    #just have return xlist + nonXList

Da Sie Python noch nicht kennen, habe ich versucht, es so einfach wie möglich zu gestalten.

2
Andy_A̷n̷d̷y̷ 6 Dez. 2013 im 20:54

Verwenden Sie Listenverständnisse

list =  ['mix', 'xyz', 'apple', 'xanadu', 'aardvark']
list.sort()
listA = [item for item in list if item[0] == 'x']
listB = [item for item in list if item[0] != 'x']
listC = listA + listB
2
tom 6 Dez. 2013 im 19:56
return sorted([w for w in words if w[0] == 'x']) + sorted([w for w in words if w[0] != 'x'])
0
Farhadix 6 Dez. 2013 im 20:13
>>> l = ['mix', 'xyz', 'apple', 'xanadu', 'aardvark'] 
>>> sorted ([x for x in l if x.startswith('x')]) + sorted([x for x in l if not x.startswith('x')])
['xanadu', 'xyz', 'aardvark', 'apple', 'mix']
1
piokuc 6 Dez. 2013 im 19:57