Existe uma função 'foreach' no Python 3?


139

Quando encontro a situação, posso fazê-lo em javascript, sempre acho que, se houver uma foreachfunção, seria conveniente. Por foreach, quero dizer a função que é descrita abaixo:

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

eles apenas fazem isso em todos os elementos e não produzem ou retornam algo, acho que deve ser uma função interna e deve ser mais rápida do que escrevê-la com Python puro, mas não a encontrei na lista, ou acabou de chamar outro nome? ou eu só sinto falta de alguns pontos aqui?

Talvez eu tenha me enganado, porque chamar uma função em Python custa alto, definitivamente não é uma boa prática para o exemplo. Em vez de um loop out, a função deve executar o loop no lado em que seu corpo se parece com este abaixo, que já foi mencionado nas sugestões de código de muitas python:

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

mas pensei que foreach ainda é bem-vindo com base nos dois fatos:

  1. Em casos normais, as pessoas simplesmente não se importam com o desempenho
  2. Às vezes, a API não aceita objetos iteráveis ​​e você não pode reescrever sua origem.

3
O que há de errado em usar apenas um forloop?

1
É exatamente forpara isso.
User2357112 suporta Monica

2
nada de errado com o loop for, apenas por conveniência
user2003548

6
@ user2357112, é desejável ter uma abreviação para chamar uma função uma vez por item de uma lista. list.each(func)é mais limpo do que for item in list: func(item)IMO. O problema é que Python tem feito um bom trabalho de substituição de favoritos funcionais como map()e filter()com compreensões lista que simplesmente estender a sua built-in fore if(que são homogêneos e legível) e uma específica .each()pode ir contra isso.
sevko

sum(0 for _ in map(f, seq))é uma solução legível.
Johannes Schaub - litb 11/06

Respostas:


171

Toda ocorrência de "foreach" que eu vi (PHP, C #, ...) faz basicamente o mesmo que a declaração "for".

Estes são mais ou menos equivalentes:

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

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

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

Então, sim, existe um "foreach" em python. É chamado "para".

O que você está descrevendo é uma função "mapa de matriz". Isso pode ser feito com a compreensão da lista em python:

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

namesCapitalized = [capitalize(n) for n in names]

5
Não é map (), porque map () acumula e retorna uma lista, enquanto foreach () não. A diferença pode ser bastante cara se você estiver repetindo uma longa lista de itens. Concordou que para () faz o truque.
Canuck

2
Eu já vi isso chamado de loop for-in .
Vox

5
Eles perguntaram sobre a função, mas você respondeu com a declaração.
Johannes Schaub - litb 12/06

@ JohannesSchaub-litb é que ele está certo ... 'pois' em python é literalmente 'foreach' conhecido em outras línguas ... em tcl para, por exemplo, um loop 'for' seria algo parecido com {coisas executadas no início de loop} {condição aqui} {coisas que são executadas em cada iteração} {comandos aqui ...} por exemplo: para {conjunto x 1} {$ x <= 10} {incr x} {coloca $ x} você também pode adicionar extra verifica dentro das chaves de iteração usando ';'. Para me faria mais sentido se ele veio aqui perguntando se python teve um verdadeiro laço 'for'
Francisco

3
@Francisco Eu também estou certo ao dizer que a Terra não é plana. Mas não vou adicioná-lo como resposta.
Johannes Schaub - litb 18/01/19

49

Python não possui uma foreachdeclaração propriamente dita . Possui forloops embutidos no idioma.

for element in iterable:
    operate(element)

Se você realmente quisesse, poderia definir sua própria foreachfunção:

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

Como observação lateral, a for element in iterablesintaxe vem da linguagem de programação ABC , uma das influências do Python.


14
Se você estiver fazendo isso por efeitos colaterais, e não pelo resultado do mapeamento, o uso mapdessa maneira não funcionará realmente no Python 3, onde mapé preguiçoso. Ou seja, agora ele retorna um iterador, não uma lista já calculada. Os efeitos colaterais não ocorrerão até que você percorra a lista resultante.
Laurence Gonsalves

Isso é verdade e certamente um ponto válido, mas a pergunta sugere que o OP provavelmente não está preocupado com essas sutilezas.
Phillip Cloud

@LaurenceGonsalves Thanks. Eu editei para fazer o primeiro exemplo correto em Python 3.
Phillip Nuvem

Isso é feio, é quase tão longo quanto o forloop e, se o iterável for longo (talvez infinito) ou os valores de retorno da função forem grandes, ele será quebrado com a MemoryError.
User2357112 suporta Monica

O que é feio? O primeiro exemplo? Claro, mas responde à pergunta. Eu também mencionei apenas o uso de um forloop simples , bem como a compreensão de listas.
Phillip Cloud

31

Outros exemplos:

Loop de Python Foreach:

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

Python para 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

9

map pode ser usado para a situação mencionada na pergunta.

Por exemplo

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

Para funções que recebem vários argumentos, mais argumentos podem ser dados para mapear:

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

Retorna uma lista no python 2.xe um iterador no python 3

Caso sua função aceite vários argumentos e os argumentos estejam na forma de tuplas (ou qualquer iterável desde o python 2.6), você pode usar itertools.starmap. (que tem uma sintaxe muito semelhante à que você estava procurando). Retorna um iterador.

Por exemplo

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

nos dá 8 e 9


3
mape foreachtem um significado diferente. mapretorna uma lista de resultado (que implica criar uma lista ou uma estrutura enumerável ou uma estrutura que será consumida e, portanto, não chamada imediatamente), foreachchama a função em cada item, ignorando o resultado.
njzk2

1
Foreachdeve retornar o resultado imediatamente. Dizer que criar iterador em vez de foreach é o preferido é uma porcaria total.
Little Alien

Usar map()quando o resultado é ignorado é um antipadrão. Você deve usar um loop for.
odie5533 23/07/19

1
Usar mape ignorar os resultados produzirá resultados indesejados no Python 3, pois mapagora é avaliado preguiçosamente apenas quando a lista resultante é consumida. Se o resultado do mapnunca for consumido, as chamadas nunca serão aplicadas.
Dmitry B.

5

Isso faz o foreach em python 3

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

for fetch in test:
    print(fetch)

7
Isso não responde à pergunta.
Boiethios


2

Se eu entendi direito, você quer dizer que, se tiver uma função 'func', deseja verificar cada item da lista se func (item) retornar true; se você for verdadeiro para todos, faça alguma coisa.

Você pode usar 'todos'.

Por exemplo: quero obter todos os números primos no intervalo de 0 a 10 em uma lista:

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))]

2

Aqui está o exemplo da construção "foreach" com acesso simultâneo aos índices do elemento no Python:

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

1

Veja este artigo . O iterador de objetos nditer do pacote numpy , introduzido no NumPy 1.6, oferece muitas maneiras flexíveis de visitar todos os elementos de uma ou mais matrizes de maneira sistemática.

Exemplo:

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]]

1

Se você está apenas procurando uma sintaxe mais concisa, pode colocar o loop for em uma linha:

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

Apenas separe as instruções adicionais com um ponto e vírgula.

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

Isso pode não estar em conformidade com o guia de estilo local, mas pode fazer sentido assim quando você está brincando no console.


0

Eu acho que isso responde à sua pergunta, porque é como um loop "para cada".
O script abaixo é válido em python (versão 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)")
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.