Czy w Pythonie 3 jest funkcja „foreach”?

139

Kiedy spotykam się z sytuacją, mogę to zrobić w javascript, zawsze myślę, czy istnieje foreach funkcja, to wygoda. Przez cały rozumiem funkcję opisaną poniżej:

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

po prostu robią to na każdym elemencie i nie zwróciły ani nie zwróciły, myślę, że powinna to być funkcja wbudowana i powinna być szybsza niż pisanie w czystym Pythonie, ale nie znalazłem tego na liście, lub po prostu nazwałem inną nazwę? czy po prostu brakuje mi tutaj niektórych punktów?

Może się pomyliłem, ponieważ wywołanie funkcji w Pythonie kosztuje dużo, zdecydowanie nie jest to dobra praktyka na przykład. Zamiast pętli out, funkcja powinna wykonywać pętlę w boku, tak jak jej ciało wygląda tak, jak to zostało wspomniane w wielu sugestiach dotyczących kodu w Pythonie:

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

ale pomyślałem, że każdy jest nadal mile widziany na podstawie dwóch faktów:

  1. W normalnych przypadkach ludzie po prostu nie dbają o wydajność
  2. Czasami API nie akceptowało iterowalnego obiektu i nie można przepisać jego źródła.
user2003548
źródło
3
Co jest złego w używaniu forsamej pętli?
1
To jest dokładnie to, do czego forsłuży.
user2357112 obsługuje Monikę
2
nic złego w pętli for, tylko dla wygody
user2003548
6
@ user2357112, pożądane jest, aby mieć skrót do wywoływania funkcji raz na element listy. list.each(func)jest czystszy niż for item in list: func(item)IMO. Problem polega na tym, że Python wykonał dobrą robotę zastępując funkcjonalne ulubione, takie jak map()i filter()wyrażeniami listowymi, które po prostu rozszerzają jego wbudowane fori if(które są jednorodne i czytelne), a specyfikacja .each()może temu przeszkodzić.
sevko,
sum(0 for _ in map(f, seq))to czytelne obejście.
Johannes Schaub - litb

Odpowiedzi:

171

Każde wystąpienie "foreach", które widziałem (PHP, C #, ...) robi w zasadzie to samo, co instrukcja "for" w Pythonie.

Są mniej więcej równoważne:

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

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

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

Więc tak, w Pythonie jest „foreach”. Nazywa się „za”.

To, co opisujesz, to funkcja „mapy tablicy”. Można to zrobić za pomocą list składanych w Pythonie:

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

namesCapitalized = [capitalize(n) for n in names]
Jo Are By
źródło
5
To nie jest map (), ponieważ map () gromadzi i zwraca listę, podczas gdy foreach () nie. Różnica może być dość droga, jeśli przeglądasz długą listę elementów. Uzgodniono, że for () załatwia sprawę.
Canuck
2
Widziałem to jako pętlę for-in .
Vox,
5
Pytali o funkcję, ale ty odpowiedziałeś za oświadczenie.
Johannes Schaub - litb
@ JohannesSchaub-litb chodzi o to, że on ma rację ... 'for' w pythonie jest dosłownie 'foreach' znane w innych językach ... w tcl np. Pętla 'for' byłaby czymś w rodzaju for {rzeczy uruchomione na początku pętla} {warunek tutaj} {rzeczy, które działają w każdej iteracji} {polecenia tutaj ...} np: dla {set x 1} {$ x <= 10} {incr x} {stawia $ x} możesz również dodać dodatkowe sprawdza wewnątrz nawiasów iteracyjnych za pomocą ';'. Dla mnie miałoby to więcej sensu, gdyby przyszedł tutaj i zapytał, czy Python ma prawdziwą pętlę
Francisco
3
@Francisco Mam rację, mówiąc, że ziemia nie jest płaska. Ale nie dodam tego jako odpowiedzi.
Johannes Schaub - litb
49

Python nie posiada foreachoświadczenie per se . Posiada forpętle wbudowane w język.

for element in iterable:
    operate(element)

Jeśli naprawdę chcesz, możesz zdefiniować własną foreachfunkcję:

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

Na marginesie, for element in iterableskładnia pochodzi z języka programowania ABC, będącego jednym z wpływów Pythona.

Phillip Cloud
źródło
14
Jeśli robisz to dla efektów ubocznych, a nie dla wyniku mapowania, to użycie mapw ten sposób nie zadziała w Pythonie 3, gdzie mapjest leniwe. Oznacza to, że teraz zwraca iterator, a nie już obliczoną listę. Efekty uboczne nie pojawią się, dopóki nie przejdziesz przez wynikową listę.
Laurence Gonsalves,
To prawda i na pewno słuszna uwaga, ale pytanie sugeruje, że PO prawdopodobnie nie zajmuje się takimi subtelnościami.
Phillip Cloud
@LaurenceGonsalves Thanks. Edytowałem, aby pierwszy przykład był poprawny w Pythonie 3.
Phillip Cloud,
To jest brzydkie, jest prawie tak długie jak forpętla, a jeśli iterowalna jest długa (być może nieskończona) lub wartości zwracane przez funkcję są duże, zrywa się z MemoryError.
user2357112 obsługuje Monikę
Co jest brzydkie? Pierwszy przykład? Jasne, ale odpowiada na pytanie. Wspomniałem też o zwykłej forpętli, a także o składaniu list.
Phillip Cloud
31

Inne przykłady:

Python Foreach Loop:

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
źródło
9

map można wykorzystać do sytuacji wspomnianej w pytaniu.

Na przykład

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

W przypadku funkcji, które przyjmują wiele argumentów, można podać więcej argumentów do odwzorowania:

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

Zwraca listę w pythonie 2.xi iterator w pythonie 3

W przypadku, gdy twoja funkcja przyjmuje wiele argumentów, a argumenty są już w postaci krotek (lub dowolnej iterowalnej od Pythona 2.6), możesz użyćitertools.starmap . (który ma bardzo podobną składnię do tego, czego szukałeś). Zwraca iterator.

Na przykład

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

daje nam 8 i 9

Akshit Khurana
źródło
3
mapi foreachmają inne znaczenie. mapzwraca listę wyników (co oznacza utworzenie listy, wyliczalnej struktury lub struktury, która zostanie zużyta, a zatem nie zostanie wywołana od razu), foreachwywołuje funkcję na każdym elemencie, ignorując wynik.
njzk2
1
Foreachmusi natychmiast zwrócić wynik. Mówienie, że tworzenie iteratora zamiast foreach jest preferowane, to totalna bzdura.
Little Alien
Używanie, map()gdy wynik jest ignorowany, jest anty-wzorcem. Zamiast tego powinieneś użyć pętli for.
odie5533
1
Używanie mapi ignorowanie wyników spowoduje niepożądane wyniki w Pythonie 3, ponieważ mapjest teraz leniwie oceniane tylko wtedy, gdy lista wynikowa jest zużyta. Jeśli wynik mapnigdy nie zostanie wykorzystany, wywołania nigdy nie są stosowane.
Dmitry B.,
5

To robi foreach w Pythonie 3

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

for fetch in test:
    print(fetch)
veera sai
źródło
7
To nie odpowiada na pytanie.
Boiethios
5

Tak, chociaż używa tej samej składni co pętla for.

for x in ['a', 'b']: print(x)
Jaskiniowiec
źródło
Niestety tak nie jestforEach
nehem
@nehem Jeśli chcesz, zawiń go w funkcję.
Jaskiniowiec
@nehem Zobacz pytanie
Caveman
2

Jeśli dobrze cię zrozumiałem, masz na myśli, że jeśli masz funkcję „func”, chcesz sprawdzić dla każdej pozycji na liście, czy funkcja func (pozycja) zwraca prawdę; jeśli osiągniesz prawdę dla wszystkich, zrób coś.

Możesz użyć „all”.

Na przykład: Chcę uzyskać listę wszystkich liczb pierwszych z zakresu 0-10:

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
źródło
2

Oto przykład konstrukcji „foreach” z jednoczesnym dostępem do indeksów elementów w Pythonie:

for idx, val in enumerate([3, 4, 5]):
    print (idx, val)
simhumileco
źródło
1

Spójrz na ten artykuł . Obiekt iteratora nditer z numpy pakietu , wprowadzony w NumPy 1.6, zapewnia wiele elastycznych sposobów odwiedzania wszystkich elementów jednej lub więcej tablic w sposób systematyczny.

Przykład:

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
źródło
1

Jeśli szukasz tylko bardziej zwięzłej składni, możesz umieścić pętlę for w jednej linii:

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

Po prostu oddziel dodatkowe instrukcje średnikiem.

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

Może to nie być zgodne z lokalnym przewodnikiem po stylu, ale może mieć sens zrobienie tego w ten sposób, gdy bawisz się w konsoli.

aris
źródło
0

Myślę, że to odpowiada na twoje pytanie, ponieważ jest to jak pętla „dla każdego”.
Poniższy skrypt działa w Pythonie (wersja 3.8):

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
źródło