Есть ли функция 'foreach' в Python 3?


139

Когда я сталкиваюсь с ситуацией, я могу сделать это в javascript, я всегда думаю, что если есть foreachфункция, это было бы удобно. Под foreach я подразумеваю функцию, которая описана ниже:

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

они просто делают это для каждого элемента и ничего не возвращают и не возвращают, я думаю, что это должна быть встроенная функция, которая должна выполняться быстрее, чем написание на чистом Python, но я не нашел ее в списке, или это просто назвали другое имя? или я просто скучаю по некоторым пунктам здесь?

Может быть, я ошибся, потому что вызов функции в Python стоит дорого, определенно не очень хорошая практика для примера. Вместо цикла out функция должна выполнять цикл в той части, в которой ее тело выглядит следующим образом, что уже упоминалось во многих предложениях кода Python:

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

но я думал, что foreach по-прежнему можно использовать на основе двух фактов:

  1. В обычных случаях люди просто не заботятся о производительности
  2. Иногда API не принимает итеративный объект, и вы не можете переписать его источник.

3
Что не так просто с использованием forцикла?

1
Это именно то for, для чего.
user2357112 поддерживает Monica

2
ничего плохого в цикле, просто для удобства
user2003548

6
@ user2357112, желательно иметь сокращение для вызова функции один раз для каждого элемента списка. list.each(func)Чище for item in list: func(item), ИМО. Проблема в том, что Python проделал хорошую работу по замене функциональных фаворитов, таких как map()и filter()списки, которые просто расширяют его встроенные forи if(которые являются однородными и читаемыми), и конкретный .each()может пойти против этого.
Севко

sum(0 for _ in map(f, seq))это читаемый обходной путь.
Йоханнес Шауб - лит

Ответы:


171

Каждый случай «foreach», который я видел (PHP, C #, ...), делает в основном то же самое, что и выражение python «for».

Это более или менее эквивалентно:

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

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

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

Так что, да, в питоне есть «foreach». Это называется "для".

То, что вы описываете, является функцией «карта массива». Это можно сделать с помощью списочных представлений в python:

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

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

5
Это не map (), потому что map () накапливает и возвращает список, а foreach () - нет. Разница может быть довольно дорогой, если вы перебираете длинный список элементов. Договорились, что for () делает свое дело.
Canuck

2
Я видел, что это называется циклом for-in .
Vox

5
Они спрашивали о функции, но вы ответили с заявлением.
Йоханнес Шауб -

@ JohannesSchaub-litb дело в том, что он прав ... 'for' в python буквально 'foreach' известен в других языках ... в tcl, например, для цикла 'for' будет что-то вроде for {штука запускается в начале цикл} {условие здесь} {материал, который выполняется на каждой итерации} {команды здесь ...} например: для {set x 1} {$ x <= 10} {incr x} {ставит $ x} вы также можете добавить дополнительные проверяет внутри фигурных скобок, используя ';'. Для меня было бы больше смысла, если бы он пришел сюда и спросил, есть ли у питона истинный цикл for
Francisco

3
@ Франциско Я также прав, говоря, что земля не плоская. Но я не буду добавлять это как ответ.
Йоханнес Шауб -

49

Python не имеет foreachутверждения как такового . Он имеет forвстроенные в язык циклы.

for element in iterable:
    operate(element)

Если вы действительно хотите, вы можете определить свою собственную foreachфункцию:

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

Как примечание стороны, for element in iterableсинтаксис происходит от языка программирования ABC , одного из влияний Python.


14
Если вы делаете это для побочных эффектов, а не для результата сопоставления, то использование mapтаким способом на самом деле не сработает в Python 3, где mapлениво. То есть теперь он возвращает итератор, а не уже вычисленный список. Побочные эффекты не будут иметь место, пока вы не выполните итерацию по полученному списку.
Лоуренс Гонсалвес

Это правда и, безусловно, верный момент, но вопрос предполагает, что ФП, вероятно, не занимается такими тонкостями.
Филип Клауд

@LaurenceGonsalves Спасибо. Я отредактировал, чтобы сделать первый пример правильным в Python 3.
Phillip Cloud

Это уродливо, это почти так же долго, как forцикл, и если повторяемая длина длинная (возможно, бесконечная) или возвращаемые значения функции большие, она разрывается с a MemoryError.
user2357112 поддерживает Monica

Что страшного? Первый пример? Конечно, но это отвечает на вопрос. Я также упомянул только использование простых forциклов и списков.
Филип Клауд

31

Другие примеры:

Цикл Python Foreach:

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

9

map может использоваться для ситуации, упомянутой в вопросе.

Например

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

Для функций, которые принимают несколько аргументов, можно указать больше аргументов для map:

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

Возвращает список в Python 2.x и итератор в Python 3

В случае, если ваша функция принимает несколько аргументов и аргументы уже представлены в виде кортежей (или любой итерируемой начиная с Python 2.6), вы можете использоватьitertools.starmap . (который имеет синтаксис, очень похожий на тот, который вы искали). Возвращает итератор.

Например

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

дает нам 8 и 9


3
mapи foreachимеют другое значение. mapвозвращает список результатов (что подразумевает создание списка, или перечислимой структуры, или структуры, которая будет использована и поэтому не foreachвызывается сразу), вызывает функцию для каждого элемента, игнорируя результат.
njzk2

1
Foreachдолжен немедленно вернуть результат. Сказать, что создание итератора вместо foreach предпочтительнее, - полная чушь.
Маленький инопланетянин

Использование, map()когда результат игнорируется, является антишаблоном. Вместо этого вы должны использовать цикл for.
odie5533

1
Использование mapи игнорирование результатов приведет к нежелательным результатам в Python 3, поскольку mapтеперь лениво оценивается только при использовании полученного списка. Если результат mapникогда не используется, вызовы никогда не применяются.
Дмитрий Б.



2

Если я вас правильно понял, вы имеете в виду, что если у вас есть функция 'func', вы хотите проверять каждый элемент в списке, если func (item) возвращает true; если у тебя все получится, то сделай что-нибудь.

Вы можете использовать «все».

Например: я хочу получить все простые числа в диапазоне 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))]

2

Вот пример конструкции foreach с одновременным доступом к индексам элементов в Python:

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

1

Посмотрите на эту статью . Объект-итератор nditer от numpy пакета , представленный в NumPy 1.6, предоставляет множество гибких способов систематического посещения всех элементов одного или нескольких массивов.

Пример:

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

Если вы просто ищете более краткий синтаксис, вы можете поместить цикл for в одну строку:

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

Просто разделите дополнительные операторы точкой с запятой.

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

Это может не соответствовать вашему местному руководству по стилю, но может иметь смысл сделать это так, когда вы играете в консоли.


0

Я думаю, что это отвечает на ваш вопрос, потому что это похоже на цикл «для каждого».
Сценарий ниже действителен в Python (версия 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)")
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.