Apakah ada fungsi 'foreach' di Python 3?

148

Ketika saya menemui situasi saya bisa melakukannya dalam javascript, saya selalu berpikir jika ada foreachfungsi itu akan memudahkan. Yang saya maksud dengan foreach adalah fungsi yang dijelaskan di bawah ini:

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

mereka hanya melakukannya pada setiap elemen dan tidak menghasilkan atau mengembalikan sesuatu, saya pikir itu harus menjadi fungsi bawaan dan harus lebih cepat daripada menulisnya dengan Python murni, tetapi saya tidak menemukannya di daftar, atau itu hanya menyebut nama lain? atau saya hanya melewatkan beberapa poin di sini?

Mungkin saya salah, karena memanggil fungsi dengan Python membutuhkan biaya tinggi, jelas bukan praktik yang baik misalnya. Daripada loop keluar, fungsi harus melakukan loop di samping tubuhnya terlihat seperti ini di bawah ini yang telah disebutkan dalam banyak saran kode python:

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

tetapi saya pikir semua masih diterima berdasarkan dua fakta:

  1. Dalam kasus normal, orang tidak peduli dengan kinerja
  2. Terkadang API tidak menerima objek yang dapat diulang dan Anda tidak dapat menulis ulang sumbernya.
pengguna2003548
sumber
3
Apa salahnya menggunakan forloop?
1
Inilah tepatnya untuk apa for.
user2357112 mendukung Monica
2
tidak ada yang salah dengan for loop, hanya untuk kenyamanan
user2003548
6
@ user2357112, sebaiknya memiliki singkatan untuk memanggil suatu fungsi sekali per item dari daftar. list.each(func)lebih bersih dari for item in list: func(item), IMO. Masalahnya adalah bahwa Python telah melakukan pekerjaan yang baik untuk mengganti favorit fungsional seperti map()dan filter()dengan pemahaman daftar yang hanya memperluas bawaannya fordan if(yang homogen dan dapat dibaca) dan yang spesifik .each()mungkin bertentangan dengan itu.
sevko
sum(0 for _ in map(f, seq))adalah solusi yang bisa dibaca.
Johannes Schaub - litb

Jawaban:

180

Setiap kemunculan "foreach" yang pernah saya lihat (PHP, C #, ...) pada dasarnya sama dengan pernyataan "untuk" ular sanca.

Ini kurang lebih setara:

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

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

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

Jadi, ya, ada "foreach" di python. Ini disebut "untuk".

Apa yang Anda gambarkan adalah fungsi "peta larik". Ini bisa dilakukan dengan pemahaman daftar di python:

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

namesCapitalized = [capitalize(n) for n in names]
Jo Are By
sumber
5
Ini bukan map (), karena map () mengumpulkan dan mengembalikan daftar, sedangkan foreach () tidak. Perbedaannya bisa sangat mahal jika Anda mengulang daftar item yang panjang. Setuju bahwa untuk () melakukan trik.
Canuck
2
Saya telah melihat ini disebut sebagai for-in loop.
Vox
6
Mereka menanyakan tentang fungsi, tetapi Anda menjawab dengan untuk pernyataan.
Johannes Schaub - litb
@ JohannesSchaub-litb masalahnya adalah bahwa dia benar ... 'karena' dalam python secara harfiah berarti 'foreach' yang dikenal dalam bahasa lain ... dalam tcl untuk misalnya loop 'untuk' akan menjadi seperti untuk {hal-hal yang dijalankan di awal loop} {kondisi di sini} {hal-hal yang berjalan pada setiap iterasi} {perintah di sini ...} misalnya: untuk {set x 1} {$ x <= 10} {incr x} {put $ x} Anda juga dapat menambahkan ekstra periksa di dalam kurung iterasi menggunakan ';'. Bagi saya akan lebih masuk akal jika dia datang ke sini menanyakan apakah python memiliki loop 'untuk' yang benar
Francisco
3
@Francisco Saya juga benar mengatakan bahwa bumi tidak datar. Tapi saya tidak akan menambahkannya sebagai jawaban.
Johannes Schaub - litb
50

Python tidak memiliki foreachpernyataan itu sendiri . Ini memiliki forloop yang dibangun ke dalam bahasa.

for element in iterable:
    operate(element)

Jika Anda benar-benar menginginkannya, Anda dapat menentukan foreachfungsi Anda sendiri :

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

Sebagai catatan tambahan for element in iterablesintaksnya berasal dari bahasa pemrograman ABC , salah satu pengaruh Python.

Phillip Cloud
sumber
14
Jika Anda melakukan ini untuk efek samping, bukan untuk hasil pemetaan, maka menggunakan mapdengan cara ini tidak benar-benar akan berhasil di Python 3 mapyang malas. Artinya, sekarang mengembalikan iterator, bukan daftar yang sudah dihitung. Efek samping tidak akan terjadi sampai Anda mengulang melalui daftar yang dihasilkan.
Laurence Gonsalves
Itu benar dan tentu saja poin yang valid, tetapi pertanyaannya menunjukkan OP mungkin tidak peduli dengan seluk-beluk semacam itu.
Phillip Cloud
@LaurenceGonsves Terima kasih. Saya telah mengedit untuk membuat contoh pertama benar dengan Python 3.
Phillip Cloud
Ini jelek, hampir sepanjang forloop, dan jika iterable panjang (mungkin tak terbatas) atau nilai kembalian fungsi besar, ia akan putus dengan a MemoryError.
user2357112 mendukung Monica
1
Diedit untuk menghapus diskusi peta.
Phillip Cloud
31

Contoh lain:

Lingkaran Kedepan Python:

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

Python Untuk 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
sumber
10

map dapat digunakan untuk situasi yang disebutkan dalam pertanyaan.

Misalnya

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

Untuk fungsi yang mengambil banyak argumen, lebih banyak argumen dapat diberikan ke peta:

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

Ini mengembalikan daftar di python 2.x dan iterator di python 3

Jika fungsi Anda mengambil banyak argumen dan argumen tersebut sudah dalam bentuk tupel (atau yang dapat diulang sejak python 2.6) yang dapat Anda gunakan itertools.starmap. (yang memiliki sintaks yang sangat mirip dengan apa yang Anda cari). Ini mengembalikan sebuah iterator.

Misalnya

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

memberi kita 8 dan 9

Akshit Khurana
sumber
3
mapdan foreachmemiliki arti yang berbeda. mapmengembalikan daftar hasil (yang menyiratkan membuat daftar, atau struktur yang dapat dihitung, atau struktur yang akan dikonsumsi, dan karena itu tidak langsung dipanggil), foreachmemanggil fungsi pada setiap item, mengabaikan hasilnya.
njzk2
1
Foreachharus segera mengembalikan hasilnya. Mengatakan bahwa membuat iterator daripada foreach lebih disukai adalah omong kosong total.
Alien Kecil
1
Menggunakan map()saat hasil diabaikan adalah anti-pola. Anda harus menggunakan for loop sebagai gantinya.
odie5533
2
Menggunakan mapdan mengabaikan hasil akan menghasilkan hasil yang tidak diinginkan dalam Python 3 karena mapsekarang malas dievaluasi hanya ketika daftar yang dihasilkan dipakai. Jika hasil dari maptidak pernah dikonsumsi, panggilan tidak akan pernah diterapkan.
Dmitry B.
5

Ini melakukan foreach di python 3

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

for fetch in test:
    print(fetch)
veera sai
sumber
8
Ini tidak menjawab pertanyaan itu.
Boiethios
5

Ya, meskipun menggunakan sintaks yang sama dengan for loop.

for x in ['a', 'b']: print(x)
Manusia Gua
sumber
Sayangnya ini bukanforEach
nehem
@nehem Bungkus dalam fungsi jika Anda mau.
Manusia Gua
@nehem Lihat pertanyaan
Manusia Gua
2

Jika saya mengerti Anda benar, maksud Anda adalah jika Anda memiliki fungsi 'func', Anda ingin memeriksa setiap item dalam daftar jika func (item) mengembalikan nilai true; jika Anda benar untuk semua, maka lakukan sesuatu.

Anda bisa menggunakan 'semua'.

Sebagai contoh: Saya ingin mendapatkan semua bilangan prima dalam kisaran 0-10 dalam daftar:

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))]
Be'ezrat Hashem
sumber
2

Berikut adalah contoh konstruksi "foreach" dengan akses simultan ke indeks elemen dengan Python:

for idx, val in enumerate([3, 4, 5]):
    print (idx, val)
simhumileco.dll
sumber
1

Lihat artikel ini . Objek iterator nditer dari paket numpy , yang diperkenalkan di NumPy 1.6, menyediakan banyak cara fleksibel untuk mengunjungi semua elemen dari satu atau lebih larik secara sistematis.

Contoh:

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
sumber
1

Jika Anda hanya mencari sintaks yang lebih ringkas, Anda dapat meletakkan loop for pada satu baris:

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

Pisahkan saja pernyataan tambahan dengan titik koma.

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

Ini mungkin tidak sesuai dengan panduan gaya lokal Anda, tetapi masuk akal untuk melakukannya seperti ini saat Anda bermain-main di konsol.

aris
sumber
0

Saya rasa ini menjawab pertanyaan Anda, karena ini seperti lingkaran "untuk setiap".
Script di bawah ini valid dalam python (versi 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)")
pengguna13067213
sumber