210

When I meet the situation I can do it in javascript, I always think if there's an foreach function it would be convenience. By foreach I mean the function which is described below:

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

they just do it on every element and didn't yield or return something,i think it should be a built-in function and should be more faster than writing it with pure Python, but I didn't found it on the list,or it just called another name?or I just miss some points here?

Maybe I got wrong, cause calling an function in Python cost high, definitely not a good practice for the example. Rather than an out loop, the function should do the loop in side its body looks like this below which already mentioned in many python's code suggestions:

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

but I thought foreach is still welcome base on the two facts:

  1. In normal cases, people just don't care about the performance
  2. Sometime the API didn't accept iterable object and you can't rewrite its source.
kenorb
  • 137,499
  • 74
  • 643
  • 694
user2003548
  • 3,899
  • 4
  • 23
  • 32
  • 4
    What's wrong with just using a `for` loop? –  Aug 18 '13 at 00:30
  • 1
    This is exactly what `for` is for. – user2357112 Aug 18 '13 at 01:02
  • 3
    nothing wrong with for loop ,just for convenience – user2003548 Aug 18 '13 at 01:12
  • 13
    @user2357112, it's desirable to have a shorthand for calling a function once per item of a list. `list.each(func)` is cleaner than `for item in list: func(item)`, IMO. The problem is that Python's done a good job of replacing functional favorites like `map()` and `filter()` with list comprehensions which simply extend its built-in `for` and `if` (which are homogeneous and readable) and a specific `.each()` might go against that. – sevko Dec 09 '14 at 16:15
  • `sum(0 for _ in map(f, seq))` is a readable workaround. – Johannes Schaub - litb Jun 11 '18 at 18:44

13 Answers13

232

Every occurence of "foreach" I've seen (PHP, C#, ...) does basically the same as pythons "for" statement.

These are more or less equivalent:

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

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

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

So, yes, there is a "foreach" in python. It's called "for".

What you're describing is an "array map" function. This could be done with list comprehensions in python:

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

namesCapitalized = [capitalize(n) for n in names]
user 451
  • 452
  • 6
  • 8
Jo Are By
  • 2,979
  • 1
  • 10
  • 10
  • 7
    It's not map(), because map() accumulates and returns a list, while foreach() doesn't. The difference could be quite expensive if you're iterating over a long list of items. Agreed that for() does the trick. – Canuck Apr 08 '15 at 17:10
  • 4
    I've seen this referred to as a __for-in__ loop. – Vox Jul 09 '15 at 21:23
  • 9
    They asked about for function, but you answered with for statement. – Johannes Schaub - litb Jun 12 '18 at 07:08
  • 1
    @JohannesSchaub-litb thing is that he is right... 'for' in python is literally 'foreach' known in other languages...in tcl for eg a 'for' loop would be something like for {stuff ran on beginning of loop} {condition here} {stuff that runs on each iteration} {commands here...} eg: for {set x 1} {$x <= 10} {incr x} {puts $x} you can also add extra checks inside the iteration braces using ';'. To me would make more sense if he came here asking if python had a true 'for' loop – Francisco Jan 18 '19 at 07:40
  • 3
    @Francisco I'm also right in saying that earth isn't flat. But I won't add it as an answer. – Johannes Schaub - litb Jan 18 '19 at 17:44
  • Is there a `foreach($array as key=>$value)` in python? – LF00 Oct 24 '19 at 00:26
  • This is not a solid answer since `foreach` is supported natively in many languages including scala, javascript, java, ruby. The difference is they are methods _on the collection itself_ not an add on external syntax. E.g. javascript `mylist.foreach( x => // do something with/to x)` – WestCoastProjects Dec 19 '20 at 10:06
67

Python doesn't have a foreach statement per se. It has for loops built into the language.

for element in iterable:
    operate(element)

If you really wanted to, you could define your own foreach function:

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

As a side note the for element in iterable syntax comes from the ABC programming language, one of Python's influences.

Phillip Cloud
  • 23,488
  • 11
  • 67
  • 88
  • 16
    If you're doing this for side-effects, rather than for the result of the mapping, then using `map` in this way isn't really going to work in Python 3 where `map` is lazy. That is, it now returns an iterator, not an already computed list. The side-effects won't take place until you iterate through the resulting list. – Laurence Gonsalves Aug 18 '13 at 00:38
  • That's true and certainly a valid point, but the question suggests the OP is probably not concerned with such subtleties. – Phillip Cloud Aug 18 '13 at 00:41
  • @LaurenceGonsalves Thanks. I've edited to make the first example correct in Python 3. – Phillip Cloud Aug 18 '13 at 00:48
  • This is ugly, it's almost as long as the `for` loop, and if the iterable is long (perhaps infinite) or the function return values are large, it breaks with a `MemoryError`. – user2357112 Aug 18 '13 at 01:05
  • What's ugly? The first example? Sure, but it answers the question. I also mentioned just using a plain `for` loop works, as well as list comprehensions. – Phillip Cloud Aug 18 '13 at 01:16
  • `map` and `foreach` are two different abstractions. `map` is supposed to return a new value while `foreach` returns no value at all. I guess the first statement in your answer leads to down votes. – yatskevich Jun 09 '16 at 13:55
  • 1
    Edited to remove the map discussion. – Phillip Cloud Jun 11 '16 at 17:18
35

Other examples:

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
  • 4,918
  • 2
  • 19
  • 34
13

map can be used for the situation mentioned in the question.

E.g.

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

For functions that take multiple arguments, more arguments can be given to map:

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

It returns a list in python 2.x and an iterator in python 3

In case your function takes multiple arguments and the arguments are already in the form of tuples (or any iterable since python 2.6) you can use itertools.starmap. (which has a very similar syntax to what you were looking for). It returns an iterator.

E.g.

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

gives us 8 and 9

Akshit Khurana
  • 624
  • 6
  • 14
  • 3
    `map` and `foreach` have different meaning. `map` returns a list of result (which implies creating a list, or an enumerable structure, or a structure that will be consumed, and therefore not called right away), `foreach` calls the function on each item, ignoring the result. – njzk2 Jun 28 '16 at 20:46
  • 1
    `Foreach` must return the result imediately. Saying that creating iterator instead of foreach is preferred is total crap. – Little Alien Jul 12 '16 at 18:35
  • 2
    Using `map()` when the result is ignored is an anti-pattern. You should use a for loop instead. – odie5533 Jul 23 '19 at 14:22
  • 2
    Using `map` and ignoring the results will produce undesired results in Python 3 since `map` is now lazily evaluated only when the resulting list is consumed. If the result of the `map` is never consumed, the calls are never applied. – Dmitry B. Dec 14 '19 at 06:31
8

The correct answer is "python collections do not have a foreach". In native python we need to resort to the external for _element_ in _collection_ syntax which is not what the OP is after.

Python is in general quite weak for functionals programming. There are a few libraries to mitigate a bit. I helped author one of these infixpy https://pypi.org/project/infixpy/

from infixpy import Seq
(Seq([1,2,3]).foreach(lambda x: print(x)))
1
2
3

Also see: Left to right application of operations on a list in Python 3

WestCoastProjects
  • 53,260
  • 78
  • 277
  • 491
7

Yes, although it uses the same syntax as a for loop.

for x in ['a', 'b']: print(x)
Caveman
  • 1,874
  • 13
  • 17
6

Here is the example of the "foreach" construction with simultaneous access to the element indexes in Python:

for idx, val in enumerate([3, 4, 5]):
    print (idx, val)
simhumileco
  • 27,137
  • 16
  • 123
  • 105
  • 1
    This is brilliant! Much cleaner than `for idx in range(len(myList)):\print(idx,myList[idx])` where `myList=[3, 4, 5]`. – Armfoot Dec 07 '20 at 21:07
5

This does the foreach in python 3

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

for fetch in test:
    print(fetch)
eyllanesc
  • 221,139
  • 17
  • 121
  • 189
veera sai
  • 102
  • 1
  • 1
3

Look at this article. The iterator object nditer from numpy package, introduced in NumPy 1.6, provides many flexible ways to visit all the elements of one or more arrays in a systematic fashion.

Example:

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
  • 2,431
  • 1
  • 24
  • 37
2

If I understood you right, you mean that if you have a function 'func', you want to check for each item in list if func(item) returns true; if you get true for all, then do something.

You can use 'all'.

For example: I want to get all prime numbers in range 0-10 in a list:

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))]
Pang
  • 9,073
  • 146
  • 84
  • 117
2

I know this is an old thread but I had a similar question when trying to do a codewars exercise.

I came up with a solution which nests loops, I believe this solution applies to the question, it replicates a working "for each (x) doThing" statement in most scenarios:

for elements in array:
    while elements in array:
        
        array.func()
Dharman
  • 26,923
  • 21
  • 73
  • 125
ET-13
  • 21
  • 3
1

If you're just looking for a more concise syntax you can put the for loop on one line:

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

Just separate additional statements with a semicolon.

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

This may not conform to your local style guide, but it could make sense to do it like this when you're playing around in the console.

aris
  • 20,635
  • 1
  • 25
  • 31
1

If you really want you can do this:

[fn(x) for x in iterable]

But the point of the list comprehension is to create a list - using it for the side effect alone is poor style. The for loop is also less typing

for x in iterable: fn(x)
AutomatedMike
  • 1,425
  • 13
  • 27