Ihr Ansatz ist ganz in Ordnung aus konzeptioneller Perspektive für jemanden, der die ersten Schritte in der Programmierung macht:
Die gute Sache ist, dass Sie nur nehmen Sie die nachfolgende Liste für jedes Element aus Ihrem erste for
Schleife in Rechnung und nicht über die gesamte Liste iterieren.
Das Schlimme ist, was Sie wahrscheinlich denken lässt, dass dies verbessert werden kann, dass Sie Socken, denen ein Paar zugewiesen wurde, markieren, anstatt sie aus der Liste zu entfernen. Wenn Sie sie entfernen, verkürzt sich die Liste und die Berechnungsschritte, die zum Beenden der Aufgabe erforderlich sind, werden reduziert. Es ist jedoch eine schlechte Idee, Elemente aus einer Liste zu entfernen, während man darüber iteriert, also brauchen Sie hier etwas anderes.
Zusätzlich können Sie die umgebende while
-Schleife weglassen, da die erste for
Schleife sowieso endet, sobald das Ende der Sockensequenz erreicht ist. Achten Sie auf IndexError
s beim Zugriff auf die nachfolgende Liste, wenn Sie das Ende erreicht haben.
Ich bezweifle, dass Sie Rekursion in der Klasse noch bedeckt, aber dies wäre ein effizienter Ansatz von Iterieren über ändernden Listen und zugleich sammelt Gegenstände, die nicht zu einem Paar zugeordnet werden können (dh einsam Socken).
Rekursion ist über eine Funktion von selbst anrufen:
Lassen socks
Ihre Eingabeliste sein. Sie können es in seine head
(das erste Element) und rest
(alle anderen Elemente) teilen.
socks = [10, 20, 10, 40]
head = socks[0] # Here, head will be 10
rest = socks[1:] # Here, rest will be [20, 10, 40]
Für den ersten Schritt müssen Sie für ein Element in rest
suchen, die zu Ihrem head
gleich ist. Einmal gefunden, können Sie es von rest
entfernen, da es nicht mehr als einmal kombiniert werden kann:
for i, s in enumerate(rest):
if s == head:
match = rest.pop(i)
break
nun nach diesem Schritt, wissen Sie, dass Sie ein Paar gefunden haben, bestehend aus den Elementen head
und match
. Und Ihre rest
Liste hat sich verändert: Sie haben das passende Teil entfernt:
[20, 40]
Sie können diese Schritte wiederholen, bis die rest
Liste der Länge ist <= 1
, so würden wir einen weiteren Lauf hier brauchen, wo head
20
sein würde und rest
wäre [40]
. Iterieren über rest
würde kein Paar ergeben und wir sollten es so wie es ist zurückgeben.
Sobald Ihre Iteration den Punkt erreicht hat, an dem die Länge rest
<= 1
ist, können Sie beenden, da Sie wissen, dass Sie alle Paare gefunden haben müssen.
In Code, könnte dies wie folgt aussehen:
import random
def seek_pair(lst):
if len(lst) <= 1:
# Nothing to do if we cannot split list into head and rest
return lst
# Split list into head and rest
head, rest = lst[0], lst[1:]
# Iterate over rest and try to find a match
match = None
for i, s in enumerate(rest):
if s == head:
# We have found an element that equals our head
# Remove it from the list and store it in variable 'match'
match = rest.pop(i)
# Break the loop as we have found a match
break
if match:
# If there was a match in the 'rest' list, we can print it
print('Pair: ({:d}, {:d})'.format(head, match))
# And call the method 'seek_pair()' on the resulting 'rest'
# Note that here, the matching element has already been
# removed from the list 'rest'.
return seek_pair(rest) # RECURSION
else:
# If no match was found, we still need to search the 'rest'
# list for other matches.
# And, since 'head' did not match any other element, we append
# it to the beginning of our result list, which will hold all
# elements without matches (i.e. lonely socks).
return [head] + seek_pair(rest) # RECURSION
if __name__ == '__main__':
# Randomly generate an input list of desired length
n = 9
socks = [random.randint(1, 9) * 10 for _ in range(n)]
# Print the list
print('Socks: {:s}'.format(', '.join([str(s) for s in socks])))
# Call the function on the entire list and obtain its result,
# that should contain all lonely socks.
rest = seek_pair(socks)
# Print lonely socks
print('Rest: {:s}'.format(', '.join([str(s) for s in rest])))
Der Ausgang dieser Code sieht wie folgt aus:
Socks: 30, 10, 30, 40, 30, 50, 40, 60, 70
Pair: (30, 30)
Pair: (40, 40)
Rest: 10, 30, 50, 60, 70
'n' nicht BTW gar –
verwendet wird, obwohl Sie sagten, Sie in alternative Lösung nicht wirklich intersted, Ihre Iterieren durch die gesamte Liste ist wirklich ineffizient. Sie können einfach die Anzahl der Vorkommen jedes einzelnen Sockenwertes zählen, sie durch 2 (abgerundet) dividieren und alles summieren. Mit "inp = 10 20 20 10 10 30 50 10 20" als Eingabe können Sie den gesamten Code durch eine Zeile ersetzen: 'print (sum ([inp.split(). Count (x) // 2 für x im Satz (inp.split())])) ' – Efferalgan
Für Code-Review müssen Sie Ihre Frage auf http://codereview.stackexchange.com – ettanany