Python 3中是否有一个“ foreach”功能?


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
for循环没什么问题,只是为了方便
user2003548

6
@ user2357112,最好有一个快捷方式来为列表的每个项目调用一次函数。list.each(func)for item in list: func(item)IMO 干净。问题是,Python的做替换样功能的最爱的一个好工作map(),并filter()与列表理解它简单地延长其内置的forif(这是均匀和可读性)和特定的.each()可能去对抗。
sevko 2014年

sum(0 for _ in map(f, seq))是一种可读的解决方法。
Johannes Schaub-litb

Answers:


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)

因此,是的,python中有一个“ foreach”。它称为“ for”。

您要描述的是“数组映射”功能。这可以通过python中的列表理解来完成:

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

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

5
它不是map(),因为map()会累积并返回一个列表,而foreach()则不会。如果要遍历一长串项目,则差异可能会非常昂贵。同意for()可以解决问题。
Canuck

2
我已经看到这称为for-in循环。
Vox

5
他们询问功能,但是您回答了。
Johannes Schaub-litb

@ JohannesSchaub-litb的事情是,他是对的...在Python中,“ for”在其他语言中实际上是“ foreach” ...在tcl中,例如,“ for”循环类似于{{循环} {条件在这里} {每次迭代中运行的东西} {命令在这里...}例如:对于{set x 1} {$ x <= 10} {incr x} {puts $ x}您还可以添加额外的内容使用“;”检查迭代括号内。对我来说会更有意义,如果他来到这里,询问是否有蟒蛇一个真正的“for”循环
旧金山

3
@Francisco我也很正确地说地球并不平坦。但我不会将其添加为答案。
Johannes Schaub-litb

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以这种方式使用实际上在map懒惰的Python 3中是行不通的。也就是说,它现在返回一个迭代器,而不是已经计算出的列表。除非您遍历结果列表,否则副作用不会发生。
Laurence Gonsalves

没错,这当然是正确的观点,但是这个问题表明,OP可能并不关心这种微妙之处。
菲利普·

@LaurenceGonsalves谢谢。我已经编辑做在Python 3的第一个例子正确
菲利普云

这很丑陋,几乎与for循环一样长,并且如果iterable很长(也许是无限的)或函数的返回值很大,则它会以a中断MemoryError
user2357112支持Monica

什么丑陋的?第一个例子?可以,但是可以回答问题。我还提到了仅使用普通for循环以及列表推导。
菲利普·乌云

31

其他例子:

Python Foreach循环:

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

Python For循环:

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
mapforeach有不同的含义。map返回结果列表(这意味着创建列表,可枚举的结构或将要使用的结构,因此不会立即调用),foreach在每个项目上调用函数,而忽略结果。
njzk2

1
Foreach必须立即返回结果。说创建迭代器而不是foreach是最好的选择。
小外星人

map()当忽略结果时使用反模式。您应该改用for循环。
odie5533 '19

1
使用map和忽略结果将在Python 3中产生不需要的结果,因为map现在仅当消耗了结果列表时才对它们进行延迟评估。如果map永不消耗的结果,则永不应用调用。
德米特里(Dmitry B)

5

这在python 3中做了foreach

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

for fetch in test:
    print(fetch)

7
这不能回答问题。
Boiethios

5

是的,尽管它使用与for循环相同的语法。

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

不幸的是,这不是forEach
nehem

@nehem如果需要,可以将其包装在函数中。
穴居人

@nehem看到问题
穴居人

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

这是可以同时访问Python中元素索引“ foreach”构造示例:

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

1

这篇文章。迭代器对象nditernumpy的包,在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

我认为这回答了您的问题,因为它就像一个“ for each”循环。
以下脚本在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)")
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.