Ich möchte fragen, ob es eine elegante pythonische Möglichkeit gibt, eine Funktion bei der ersten Schleifeniteration auszuführen. Die einzige Möglichkeit, an die ich denken kann, ist:
first = True
for member in something.get():
if first:
root.copy(member)
first = False
else:
somewhereElse.copy(member)
foo(member)
member
diese Weise verschmutzen Sie den Namespace mit einem Extra .member
. Einermember
war der Kopf; der anderemembers
wo der Schwanz. Sie waren jedoch alle Mitglieder. Ich bin mir nicht sicher, welchen Punkt du machst.foo
an zwei (oder mehr) Stellen gegen DRY verstößt. Es ist eine Funktion, die wiederverwendet wird. Ist das nicht der Punkt einer Funktionsdefinition?So etwas sollte funktionieren.
for i, member in enumerate(something.get()): if i == 0: # Do thing # Code for everything
Ich würde jedoch dringend empfehlen, über Ihren Code nachzudenken, um zu sehen, ob Sie es wirklich so machen müssen, weil es irgendwie "schmutzig" ist. Besser wäre es, das Element, das eine spezielle Behandlung benötigt, im Voraus abzurufen und dann eine regelmäßige Behandlung für alle anderen in der Schleife durchzuführen.
Der einzige Grund, warum ich es nicht so machen konnte, war eine große Liste, die Sie von einem Generatorausdruck erhalten würden (den Sie nicht im Voraus abrufen möchten, weil er nicht in den Speicher passt) oder ähnliche Situationen .
quelle
for i, a, b, c, in os.walk(input_dir):
? Das gibtValueError: need more than 3 values to unpack
.python for i,tuple in enumerate(os.walk(...)): a, b, c = tuple
wie wäre es mit:
my_array = something.get() for member in my_array: if my_array.index(member) == 0: root.copy(member) else: somewhereElse.copy(member) foo(member)
oder vielleicht:
for index, member in enumerate(something.get()): if index == 0: root.copy(member) else: somewhereElse.copy(member) foo(member)
Dokumentation der Indexmethode .
quelle
if member is my_array[0]
. Dies funktioniert jedoch immer noch nicht, wenn my_array auf dasselbe Objekt bei Index 0 und einen anderen Index verweist.Das funktioniert:
for number, member in enumerate(something.get()): if not number: root.copy(member) else: somewhereElse.copy(member) foo(member)
In den meisten Fällen würde ich jedoch vorschlagen, nur zu wiederholen
whatever[1:]
und die Root-Sache außerhalb der Schleife auszuführen. das ist normalerweise besser lesbar. Kommt natürlich auf deinen Anwendungsfall an.quelle
Hier könnte ich mit einer pythonischen Sprache kommen, die "pertty" aussehen kann. Obwohl ich höchstwahrscheinlich das Formular verwenden würde, das Sie beim Stellen der Frage vorgeschlagen haben, nur damit der Code offensichtlicher, wenn auch weniger elegant bleibt.
def copy_iter(): yield root.copy while True: yield somewhereElse.copy for member, copy in zip(something.get(), copy_iter()): copy(member) foo(member)
(Entschuldigung - das erste Formular, das ich vor dem Bearbeiten gepostet habe, würde nicht funktionieren. Ich hatte vergessen, tatsächlich einen Iterator für das 'Kopier'-Objekt zu erhalten.)
quelle
Ich denke, das ist ziemlich elegant, aber vielleicht zu kompliziert für das, was es tut ...
from itertools import chain, repeat, izip for place, member in izip(chain([root], repeat(somewhereElse)), something.get()): place.copy(member) foo(member)
quelle
Wenn etwas.get () über etwas iteriert, können Sie dies auch wie folgt tun:
root.copy(something.get()) for member in something.get(): # the rest of the loop
quelle
Ich denke, die erste S.Lott-Lösung ist die beste, aber es gibt eine andere Wahl, wenn Sie eine ziemlich aktuelle Python verwenden (> = 2.6, da izip_longest vor dieser Version nicht verfügbar zu sein scheint), mit der Sie verschiedene Dinge für die erstes und aufeinanderfolgendes Element und kann leicht modifiziert werden, um unterschiedliche Operationen für das 1., 2., 3. Element auszuführen ... auch.
from itertools import izip_longest seq = [1, 2, 3, 4, 5] def headfunc(value): # do something print "1st value: %s" % value def tailfunc(value): # do something else print "this is another value: %s" % value def foo(value): print "perform this at ANY iteration." for member, func in izip_longest(seq, [headfunc], fillvalue=tailfunc): func(member) foo(member)
quelle
Wie wäre es
iter
, das erste Element zu verwenden und zu konsumieren?Bearbeiten: Zurück zur Frage des OP: Es gibt eine gemeinsame Operation, die Sie für alle Elemente ausführen möchten, und dann eine Operation, die Sie für das erste Element ausführen möchten, und eine andere für den Rest.
Wenn es sich nur um einen einzelnen Funktionsaufruf handelt, würde ich sagen, schreiben Sie ihn einfach zweimal. Es wird die Welt nicht beenden. Wenn es mehr involviert ist, können Sie einen Dekorateur verwenden, um Ihre "erste" Funktion und "Ruhe" -Funktion mit einer gemeinsamen Operation zu verpacken.
def common(item): print "common (x**2):", item**2 def wrap_common(func): """Wraps `func` with a common operation""" def wrapped(item): func(item) common(item) return wrapped @wrap_common def first(item): """Performed on first item""" print "first:", item+2 @wrap_common def rest(item): """Performed on rest of items""" print "rest:", item+5 items = iter(range(5)) first(items.next()) for item in items: rest(item)
Ausgabe:
first: 2 common (x**2): 0 rest: 6 common (x**2): 1 rest: 7 common (x**2): 4 rest: 8 common (x**2): 9 rest: 9 common (x**2): 16
oder du könntest ein Stück machen:
first(items[0]) for item in items[1:]: rest(item)
quelle
Kannst du nicht
root.copy(something.get())
vor der Schleife tun ?EDIT: Sorry, ich habe das zweite Bit verpasst. Aber Sie bekommen die allgemeine Idee. Andernfalls aufzählen und prüfen nach
0
?EDIT2: Ok, habe die dumme zweite Idee losgeworden.
quelle
Ich kenne Python nicht, aber ich verwende fast das genaue Muster Ihres Beispiels.
Was ich auch mache,
if
ist die häufigste Erkrankung. Überprüfen Sie daher normalerweise,if( first == false )
warum? Bei langen Schleifen ist die erste nur einmal wahr und die anderen Male falsch, was bedeutet, dass das Programm in allen Schleifen außer der ersten nach dem Zustand sucht und zum anderen Teil springt.
Wenn überprüft wird, ob zuerst falsch ist, wird nur ein Sprung zum anderen Teil ausgeführt. Ich weiß nicht wirklich, ob dies überhaupt zu mehr Effizienz führt, aber ich mache es trotzdem, nur um mit meinem inneren Nerd in Frieden zu sein.
PS: Ja, ich weiß, dass beim Eingeben des if-Teils auch über das else gesprungen werden muss, um die Ausführung fortzusetzen. Daher ist meine Vorgehensweise wahrscheinlich nutzlos, aber es fühlt sich gut an. : D.
quelle
Ihre Frage ist widersprüchlich. Sie sagen "Mach nur etwas bei der ersten Iteration", wenn Sie tatsächlich sagen, machen Sie etwas anderes bei der ersten / nachfolgenden Iteration. So würde ich es versuchen:
copyfn = root.copy for member in something.get(): copyfn(member) foo(member) copyfn = somewhereElse.copy
quelle
Folgendes funktioniert bei mir
dup_count = 0 for x in reversed(dup_list): dup_count += 1 if dup_count == 1: print("First obj {}: {}".format(dup_count,x)) else: print("Object # {}: {}".format( dup_count,x ))
quelle