Есть ли функция '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.