Gibt es in Python 3 eine 'foreach'-Funktion?

138

Wenn ich auf die Situation stoße, in der ich es in Javascript tun kann, denke ich immer, wenn es eine foreachFunktion gibt, wäre es bequem. Mit foreach meine ich die Funktion, die unten beschrieben wird:

def foreach(fn,iterable):
    for x in iterable:
        fn(x)

Sie machen es einfach für jedes Element und haben nichts zurückgegeben oder zurückgegeben. Ich denke, es sollte eine eingebaute Funktion sein und schneller als das Schreiben mit reinem Python, aber ich habe es nicht auf der Liste gefunden, oder es hat nur einen anderen Namen genannt oder ich vermisse hier nur einige Punkte?

Vielleicht habe ich mich geirrt, weil das Aufrufen einer Funktion in Python hohe Kosten verursacht hat, definitiv keine gute Praxis für das Beispiel. Anstelle einer Out-Schleife sollte die Funktion die Schleife in der Seite ausführen, in der ihr Körper wie folgt aussieht, was bereits in vielen Python-Code-Vorschlägen erwähnt wurde:

def fn(*args):
    for x in args:
       dosomething

aber ich dachte, foreach ist immer noch eine willkommene Grundlage für die beiden Fakten:

  1. Im Normalfall kümmern sich die Leute einfach nicht um die Leistung
  2. Manchmal hat die API kein iterierbares Objekt akzeptiert und Sie können die Quelle nicht neu schreiben.
user2003548
quelle
3
Was ist falsch daran, nur eine forSchleife zu verwenden?
1
Genau dafür forist.
user2357112 unterstützt Monica
2
nichts falsch mit for-Schleife, nur der
Einfachheit halber
6
@ user2357112, es ist wünschenswert, eine Kurzform zum Aufrufen einer Funktion einmal pro Element einer Liste zu haben. list.each(func)ist sauberer als for item in list: func(item)IMO. Das Problem ist, dass Python gute Arbeit geleistet hat, um funktionale Favoriten wie map()und filter()durch Listenverständnisse zu ersetzen, die einfach das eingebaute forund if(homogen und lesbar) erweitern, und ein bestimmtes .each()könnte dagegen sprechen .
Sevko
sum(0 for _ in map(f, seq))ist eine lesbare Problemumgehung.
Johannes Schaub - litb

Antworten:

170

Jedes Vorkommen von "foreach", das ich gesehen habe (PHP, C #, ...), macht im Grunde dasselbe wie die "for" -Anweisung von Python.

Diese sind mehr oder weniger gleichwertig:

// PHP:
foreach ($array as $val) {
    print($val);
}

// C#
foreach (String val in array) {
    console.writeline(val);
}

// Python
for val in array:
    print(val)

Also, ja, es gibt ein "foreach" in Python. Es heißt "für".

Was Sie beschreiben, ist eine "Array Map" -Funktion. Dies könnte mit Listenverständnissen in Python geschehen :

names = ['tom', 'john', 'simon']

namesCapitalized = [capitalize(n) for n in names]
Jo sind vorbei
quelle
5
Es ist nicht map (), da map () eine Liste akkumuliert und zurückgibt, während foreach () dies nicht tut. Der Unterschied kann sehr teuer sein, wenn Sie eine lange Liste von Elementen durchlaufen. Einverstanden, dass for () den Trick macht.
Canuck
2
Ich habe gesehen, dass dies als For-In- Schleife bezeichnet wird.
Vox
5
Sie fragten nach der Funktion, aber Sie antworteten mit einer Erklärung.
Johannes Schaub - litb
@ JohannesSchaub-litb Sache ist, dass er Recht hat ... 'für' in Python ist wörtlich 'foreach' in anderen Sprachen bekannt ... in tcl für zB wäre eine 'for'-Schleife so etwas wie für {stuff lief am Anfang von Schleife} {Bedingung hier} {Zeug, das bei jeder Iteration ausgeführt wird} {Befehle hier ...} Beispiel: Für {set x 1} {$ x <= 10} {incr x} {setzt $ x} können Sie auch zusätzliche hinzufügen prüft innerhalb der Iterationsklammern mit ';'. Für mich wäre es sinnvoller, wenn er hierher käme und fragen würde, ob Python eine echte 'for'-Schleife hätte
Francisco
3
@ Francisco Ich habe auch Recht zu sagen, dass die Erde nicht flach ist. Aber ich werde es nicht als Antwort hinzufügen.
Johannes Schaub - litb
49

Python hat per se keine foreachAussage . In die Sprache sind Schleifen eingebaut.for

for element in iterable:
    operate(element)

Wenn Sie wirklich wollten, können Sie Ihre eigene foreachFunktion definieren :

def foreach(function, iterable):
    for element in iterable:
        function(element)

Nebenbei bemerkt for element in iterablestammt die Syntax aus der Programmiersprache ABC , einem der Einflüsse von Python.

Phillip Cloud
quelle
14
Wenn Sie dies eher für Nebenwirkungen als für das Ergebnis des Mappings tun map, funktioniert die Verwendung auf diese Weise in Python 3, wo mapes faul ist, nicht wirklich . Das heißt, es wird jetzt ein Iterator zurückgegeben, keine bereits berechnete Liste. Die Nebenwirkungen treten erst auf, wenn Sie die resultierende Liste durchlaufen.
Laurence Gonsalves
Das ist wahr und sicherlich ein gültiger Punkt, aber die Frage legt nahe, dass sich das OP wahrscheinlich nicht mit solchen Feinheiten befasst.
Phillip Cloud
@LaurenceGonsalves Danke. Ich habe bearbeitet, um das erste Beispiel in Python 3 korrekt zu machen.
Phillip Cloud
Dies ist hässlich, es ist fast so lang wie die forSchleife, und wenn die Iterable lang (möglicherweise unendlich) ist oder die Funktionsrückgabewerte groß sind, wird sie mit a unterbrochen MemoryError.
user2357112 unterstützt Monica
Was ist hässlich? Das erste Beispiel? Sicher, aber es beantwortet die Frage. Ich erwähnte auch, dass nur die Verwendung einer einfachen forSchleife funktioniert, sowie das Verständnis der Liste.
Phillip Cloud
31

Andere Beispiele:

Python Foreach-Schleife:

array = ['a', 'b']
for value in array:
    print(value)
    # a
    # b

Python For Loop:

array = ['a', 'b']
for index in range(len(array)):
    print("index: %s | value: %s" % (index, array[index]))
    # index: 0 | value: a
    # index: 1 | value: b
uingtea
quelle
8

map kann für die in der Frage genannte Situation verwendet werden.

Z.B

map(len, ['abcd','abc', 'a']) # 4 3 1

Für Funktionen, die mehrere Argumente annehmen, können der Zuordnung weitere Argumente zugewiesen werden:

map(pow, [2, 3], [4,2]) # 16 9

Es gibt eine Liste in Python 2.x und einen Iterator in Python 3 zurück

Falls Ihre Funktion mehrere Argumente akzeptiert und die Argumente bereits in Form von Tupeln (oder iterierbaren seit Python 2.6) vorliegen, können Sie diese verwenden itertools.starmap. (die eine sehr ähnliche Syntax hat wie das, wonach Sie gesucht haben). Es wird ein Iterator zurückgegeben.

Z.B

for num in starmap(pow, [(2,3), (3,2)]):
    print(num)

gibt uns 8 und 9

Akshit Khurana
quelle
3
mapund foreachhaben unterschiedliche Bedeutung. mapGibt eine Ergebnisliste zurück (was bedeutet, dass eine Liste oder eine Aufzählungsstruktur oder eine Struktur erstellt wird, die verbraucht wird und daher nicht sofort aufgerufen wird), foreachruft die Funktion für jedes Element auf und ignoriert das Ergebnis.
NJZK2
1
Foreachmuss das Ergebnis sofort zurückgeben. Zu sagen, dass das Erstellen eines Iterators anstelle von foreach bevorzugt wird, ist totaler Mist.
Little Alien
Verwenden , map()wenn das Ergebnis ignoriert wird , ist ein Anti-Muster. Sie sollten stattdessen eine for-Schleife verwenden.
odie5533
1
Das Verwenden mapund Ignorieren der Ergebnisse führt in Python 3 zu unerwünschten Ergebnissen, da diese mapnur dann träge ausgewertet werden, wenn die resultierende Liste verwendet wird. Wenn das Ergebnis von mapnie verbraucht wird, werden die Anrufe nie angewendet.
Dmitry B.
5

Dies macht den foreach in Python 3

test = [0,1,2,3,4,5,6,7,8,"test"]

for fetch in test:
    print(fetch)
veera sai
quelle
7
Dies beantwortet die Frage nicht.
Boiethios
5

Ja, obwohl es dieselbe Syntax wie eine for-Schleife verwendet.

for x in ['a', 'b']: print(x)
Höhlenmensch
quelle
Leider ist dies nichtforEach
nehem
@nehem Wickeln Sie es in eine Funktion ein, wenn Sie möchten.
Höhlenmensch
@nehem Siehe Frage
Höhlenmensch
2

Wenn ich Sie richtig verstanden habe, meinen Sie, wenn Sie eine Funktion 'func' haben, möchten Sie für jedes Element in der Liste überprüfen, ob func (Element) true zurückgibt. Wenn Sie für alle wahr werden, dann tun Sie etwas.

Sie können "alle" verwenden.

Zum Beispiel: Ich möchte alle Primzahlen im Bereich von 0 bis 10 in einer Liste erhalten:

from math import sqrt
primes = [x for x in range(10) if x > 2 and all(x % i !=0 for i in range(2, int(sqrt(x)) + 1))]
Be'ezrat Hashem
quelle
2

Hier ist das Beispiel der "foreach" -Konstruktion bei gleichzeitigem Zugriff auf die Elementindizes in Python:

for idx, val in enumerate([3, 4, 5]):
    print (idx, val)
simhumileco
quelle
1

Schauen Sie sich diesen Artikel an . Das Iteratorobjekt nditer von numpy in NumPy 1.6 eingeführte Paket bietet viele flexible Möglichkeiten, um alle Elemente eines oder mehrerer Arrays systematisch aufzurufen.

Beispiel:

import random
import numpy as np

ptrs = np.int32([[0, 0], [400, 0], [0, 400], [400, 400]])

for ptr in np.nditer(ptrs, op_flags=['readwrite']):
    # apply random shift on 1 for each element of the matrix
    ptr += random.choice([-1, 1])

print(ptrs)

d:\>python nditer.py
[[ -1   1]
 [399  -1]
 [  1 399]
 [399 401]]
FooBar167
quelle
1

Wenn Sie nur nach einer präziseren Syntax suchen, können Sie die for- Schleife in eine Zeile setzen:

array = ['a', 'b']
for value in array: print(value)

Trennen Sie einfach zusätzliche Anweisungen mit einem Semikolon.

array = ['a', 'b']
for value in array: print(value); print('hello')

Dies entspricht möglicherweise nicht Ihrem lokalen Styleguide, aber es kann sinnvoll sein, dies so zu tun, wenn Sie in der Konsole herumspielen.

aris
quelle
0

Ich denke, dies beantwortet Ihre Frage, weil es wie eine "für jede" Schleife ist.
Das folgende Skript ist in Python (Version 3.8) gültig:

a=[1,7,77,7777,77777,777777,7777777,765,456,345,2342,4]
if (n := len(a)) > 10:
    print(f"List is too long ({n} elements, expected <= 10)")
user13067213
quelle