Чи є в Python 3 функція "foreach"?


139

Коли я зустрічаюся з ситуацією, я можу це робити в JavaScript, я завжди думаю, що якщо є foreachфункція, це було б зручністю. Під формою я маю на увазі функцію, описану нижче:

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

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

Можливо, я помилився, тому що виклик функції в Python коштував дорожче, безумовно, не найкраща практика для прикладу. Замість того, щоб виходити з циклу, функція повинна робити цикл у тій стороні його тіла, як виглядає нижче, що вже згадувалося в багатьох пропозиціях щодо коду python:

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

але я подумав, що передбачення все ще вітається на двох фактах:

  1. У звичайних випадках людей просто не хвилює продуктивність
  2. Іноді API не сприйняв об'єкт, який можна відтворити, і ви не можете переписати його джерело.

3
Що поганого в тому, щоб просто використовувати forцикл?

1
Це саме те for, для чого.
user2357112 підтримує Моніку

2
нічого поганого для циклу, просто для зручності
user2003548

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

sum(0 for _ in map(f, seq))є читаним вирішенням проблеми.
Йоханнес Шауб - ліб

Відповіді:


171

Кожне виникнення «передбачення», яке я бачив (PHP, C #, ...) в основному те саме, що і пітони «for».

Вони є більш-менш еквівалентними:

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

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

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

Отже, так, в пітоні є "передбачення". Це називається "за".

Ви описуєте функцію "карта масиву". Це можна зробити за допомогою розуміння списку в python:

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

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

5
Це не map (), тому що map () накопичує та повертає список, тоді як foreach () не робить. Різниця може бути досить дорогою, якщо ви повторюєте довгий список предметів. Погодився, що для () робить трюк.
Канук

2
Я це бачив як цикл для введення .
Vox

5
Вони запитували про функцію, але ви відповіли за твердженням.
Йоханнес Шауб -

@ JohannesSchaub-litb річ у тому, що він правий ... 'для' в python буквально 'foreach', відомий іншими мовами ... цикл} {умова тут} {матеріал, який працює на кожній ітерації} {команди тут ...} наприклад: для {set x 1} {$ x <= 10} {incr x} {ставить $ x} ви також можете додати додаткові перевіряє всередині дужок ітерації за допомогою ';'. Мені було б більше сенсу, якби він прийшов сюди, запитуючи, чи справді у пітона справжній цикл «for»
Франциско,

3
@Francisco Я також правий, кажучи, що земля не рівна. Але я не додаю це як відповідь.
Йоханнес Шауб - ліб

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лінь. Тобто тепер він повертає ітератор, а не вже обчислений список. Побічні ефекти не матимуть місце, поки ви не повторите список, що випливає.
Лоранс Гонсалвс

Це правда і, безумовно, справедливий момент, але питання передбачає, що ОП, мабуть, не стосується таких тонкощів.
Phillip Cloud

@LaurenceGonsalves Дякую Я редагував, щоб зробити перший приклад правильним у Python 3.
Phillip Cloud

Це некрасиво, воно майже дорівнює forциклу, і якщо ітерабельний цикл довгий (можливо, нескінченний) або значення повернення функції великі, він розривається з a MemoryError.
user2357112 підтримує Моніку

Що потворного? Перший приклад? Звичайно, але це відповідає на питання. Я також згадав про використання простого forциклу робіт, а також про розуміння списку.
Філліп Хмара

31

Інші приклади:

Петля передбачення Python:

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

Пітон для циклу:

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(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()коли результат ігнорується, є анти-шаблоном. Слід використовувати замість циклу.
odie5533

1
Використання mapта ігнорування результатів призведе до небажаних результатів у Python 3, оскільки mapтепер ліниво оцінюється лише тоді, коли отриманий список буде використаний. Якщо результат mapніколи не споживається, дзвінки ніколи не застосовуються.
Дмитро Б.

5

Це робить передбачення в python 3

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

for fetch in test:
    print(fetch)

7
Це не дає відповіді на запитання.
Boiethios

5

Так, хоча він використовує той самий синтаксис, що і для циклу.

for x in ['a', 'b']: print(x)

На жаль, це не такforEach
nehem

@nehem Включіть його у функцію, якщо бажаєте.
Печера

@nehem Дивіться питання
Caveman

2

Якщо я зрозумів, що ви правильно, ви маєте на увазі, що якщо у вас є функція 'func', ви хочете перевірити кожен елемент у списку, чи функція (елемент) повертає істину; якщо ти справдишся для всіх, то роби щось.

Ви можете використовувати "все".

Наприклад: Я хочу отримати всі прості числа в діапазоні 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.