Abaikan nilai balik multipel python

274

Katakanlah saya memiliki fungsi Python yang mengembalikan beberapa nilai dalam sebuah tuple:

def func():
    return 1, 2

Apakah ada cara yang baik untuk mengabaikan salah satu hasil daripada hanya menetapkan ke variabel sementara? Katakanlah jika saya hanya tertarik pada nilai pertama, apakah ada cara yang lebih baik dari ini:

x, temp = func()
Tikar
sumber
2
Saya ingin tahu tentang hal ini juga datang dari konsep Matlab yang sama tentang Abaikan Fungsi Output di mana mereka gunakan ~sebagai sintaks untuk mengabaikan variabel pengembalian tertentu
jxramos
3
Anda memilih jawaban yang salah sebagai solusi
AGP

Jawaban:

242

Satu konvensi yang umum adalah menggunakan "_" sebagai nama variabel untuk elemen tuple yang ingin Anda abaikan. Misalnya:

def f():
    return 1, 2, 3

_, _, x = f()
Brian Clapper
sumber
89
-1: "konvensi" ini menyebalkan ketika Anda menambahkan fungsionalitas gettext ke kode orang lain (yang mendefinisikan fungsi yang disebut '_') jadi itu harus dilarang
nosklo
27
Poin bagus - meskipun masih bisa diperdebatkan apakah desakan gettext untuk menginstal fungsi yang disebut " " adalah ide yang bagus. Secara pribadi, saya merasa sedikit jelek. Terlepas dari itu, penggunaan " " sebagai variabel sekali pakai tersebar luas.
Brian Clapper
25
-1: _ berarti "keluaran terakhir" di IPython. Saya tidak akan pernah menetapkan sesuatu untuk itu.
Endolith
20
Ok, saya tidak memperhatikan "saya" - terima kasih untuk referensi. IMHO Anda tidak dapat mengharapkan orang lain untuk tidak menggunakan variabel hanya karena satu aplikasi Python mendefinisikan penggunaan magisnya sendiri untuk itu.
Draemon
8
beberapa IDE seperti PyDev akan memberi Anda peringatan tentang ini, karena Anda memiliki variabel yang tidak digunakan.
teeks99
595

Anda dapat menggunakan x = func()[0]untuk mengembalikan nilai pertama, x = func()[1]untuk mengembalikan nilai kedua, dan seterusnya.

Jika Anda ingin mendapatkan beberapa nilai sekaligus, gunakan sesuatu seperti x, y = func()[2:4].

Luke Woodward
sumber
92
Ini harus menjadi jawaban yang diterima. Anda juga dapat menggunakan hal-hal sepertifunc()[2:4] jika Anda hanya menginginkan beberapa nilai pengembalian.
endolith
11
Itu tidak memanggil fungsi beberapa kali: >>> def test (): ... cetak "di sini" ... kembalikan 1,2,3 ... >>> a, b = test () [: 2 ] di sini [edit: maaf kode tidak sampai, aparently Anda hanya mendapatkan satu baris dalam komentar. Bagi mereka yang tidak terbiasa >>> dan ... adalah awal dari baris baru di shell python]
teeks99
32
@ TylerLong: Saya pikir _, _, _, _, _, _, _, _, _, _, _, _, _, a, _, _, _, _, _, _, _, _, _, _, _, b, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, c, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, d, _, _, _, _, _, _, _, _, e, _ = func()kurang jelas daripada memanggil fungsi beberapa kali, tapi itu hanya pendapat saya. Jika fungsi Anda mengembalikan banyak item, saya pikir menggunakan numpy akan lebih baik:a, b, c, d, e = func()[[13, 25, 58, 89, 98]]
endolith
24
@endolith Saya pikir ini lebih baik dan tidak perlu numpy dan tidak perlu memanggil func () beberapa kali: result = func() a = result[13] b = result[25] ...
Tyler Long
3
Gaya ini tidak baik ketika Anda ingin mengabaikan satu atau beberapa nilai di antaranya, misalnyax, __, y = func()
ndemou
96

Jika Anda menggunakan Python 3, Anda dapat menggunakan bintang sebelum variabel (di sebelah kiri tugas) untuk menjadikannya daftar pembongkaran.

# Example 1: a is 1 and b is [2, 3]

a, *b = [1, 2, 3]

# Example 2: a is 1, b is [2, 3], and c is 4

a, *b, c = [1, 2, 3, 4]

# Example 3: b is [1, 2] and c is 3

*b, c = [1, 2, 3]       

# Example 4: a is 1 and b is []

a, *b = [1]
Joe
sumber
2
Anda juga dapat menggunakan a, *_ = f()untuk mengabaikan jumlah nilai yang dikembalikan setelahnya a.
THN
21

Ingat, ketika Anda mengembalikan lebih dari satu item, Anda benar-benar mengembalikan tuple. Jadi Anda dapat melakukan hal-hal seperti ini:

def func():
    return 1, 2

print func()[0] # prints 1
print func()[1] # prints 2
Evan Fosmark
sumber
17

Praktik umum adalah menggunakan variabel dummy _(underscore tunggal), seperti yang telah ditunjukkan banyak orang di sini sebelumnya.

Namun, untuk menghindari tabrakan dengan penggunaan lain dari nama variabel itu (lihat respons ini ) mungkin lebih baik menggunakan __(menggandakan garis bawah) daripada sebagai variabel sekali pakai, seperti yang ditunjukkan oleh ncoghlan . Misalnya:

x, __ = func()
lesu
sumber
Bukan ide yang buruk sama sekali. Tapi kemudian '_ _' akan mendeklarasikan variabel di namespace. Sedangkan, '_' tidak menyatakan kecuali secara khusus digunakan di sisi kiri pernyataan penugasan seperti di atas (misalnya:) a, _, _ = 1,8,9. Sampai saat itu, ia menyimpan hasil dari pernyataan terakhir dieksekusi yang jika Anda ingin menangkap, Anda biasanya akan menggunakan variabel untuk menyimpan nilai itu. Dan inilah sebabnya, '_' adalah nama variabel yang disarankan untuk menangkap nilai sampah. Nilai-nilai '_' ditimpa segera setelah pernyataan lain dieksekusi. Dalam kasus '_ _', nilai akan tetap ada sampai GC membersihkannya.
Archit Kapoor
16

Tiga pilihan sederhana.

Jelas

x, _ = func()

x, junk = func()

Mengerikan

x = func()[0]

Dan ada cara untuk melakukan ini dengan dekorator.

def val0( aFunc ):
    def pick0( *args, **kw ):
        return aFunc(*args,**kw)[0]
    return pick0

func0= val0(func)
S.Lott
sumber
5
Saya sangat suka _variabel. Sangat jelas bahwa Anda mengabaikan nilai
Claudiu
21
Contoh Anda mundur. x, _ = func()mengerikan, dan x = func()[0]jelas. Menetapkan variabel dan kemudian tidak menggunakannya? Fungsi mengembalikan tuple; indeks itu seperti tuple.
endolith
6
Dalam bahasa pencocokan pola, dari mana Python berasal pola ini, metode 'jelas' memang jelas, tidak mengerikan, dan kanonik. Meskipun, dalam bahasa tersebut wildcard adalah fitur bahasa yang didukung sedangkan dalam Python itu adalah variabel nyata dan terikat, yang sedikit tidak menyenangkan.
Joe
4
Untuk bahasa pemroses daftar, dari mana Python diturunkan ;), daftar pengakses seperti a[0], a[:](daftar salinan), a[::2](setiap dua elemen), dan a[i:] + a[:i](memutar daftar), memang, juga jelas dan kanonik.
cod3monk3y
7

Solusi terbaik mungkin adalah memberi nama sesuatu daripada mengembalikan tuple yang tidak berarti. Kecuali ada logika di balik urutan barang yang dikembalikan.

def func():
    return {'lat': 1, 'lng': 2}

latitude = func()['lat']

Anda bahkan dapat menggunakan namedtuple jika Anda ingin menambahkan informasi tambahan tentang apa yang Anda kembalikan (ini bukan hanya kamus, ini adalah koordinat):

from collections import namedtuple 

Coordinates = namedtuple('Coordinates', ['lat', 'lng'])

def func():
    return Coordinates(lat=1, lng=2)

latitude = func().lat

Jika objek dalam kamus / tuple Anda sangat terikat bersama-sama maka mungkin ide yang baik untuk bahkan menentukan kelas untuk itu. Dengan begitu Anda juga akan dapat mendefinisikan interaksi antara objek-objek jenis ini dan memberikan API tentang cara bekerja dengannya. Pertanyaan alami yang mengikuti: Kapan saya harus menggunakan kelas dengan Python? .

cglacet
sumber
4

Ini sepertinya pilihan terbaik bagi saya:

val1, val2, ignored1, ignored2 = some_function()

Ini tidak samar atau jelek (seperti metode func () [index]), dan dengan jelas menyatakan tujuan Anda.

kmelvn
sumber
4

Ini bukan jawaban langsung untuk pertanyaan itu. Melainkan menjawab pertanyaan ini: "Bagaimana saya memilih output fungsi spesifik dari banyak opsi yang mungkin?".

Jika Anda dapat menulis fungsi (mis., Itu tidak ada di perpustakaan yang tidak dapat Anda modifikasi), kemudian tambahkan argumen input yang menunjukkan apa yang Anda inginkan dari fungsi tersebut. Buatlah argumen bernama dengan nilai default sehingga dalam "kasus umum" Anda bahkan tidak harus menentukannya.

    def fancy_function( arg1, arg2, return_type=1 ):
        ret_val = None
        if( 1 == return_type ):
            ret_val = arg1 + arg2
        elif( 2 == return_type ):
            ret_val = [ arg1, arg2, arg1 * arg2 ]
        else:
            ret_val = ( arg1, arg2, arg1 + arg2, arg1 * arg2 ) 
        return( ret_val )

Metode ini memberikan fungsi "peringatan lanjutan" tentang output yang diinginkan. Akibatnya ia dapat melewati pemrosesan yang tidak dibutuhkan dan hanya melakukan pekerjaan yang diperlukan untuk mendapatkan hasil yang diinginkan. Juga karena Python melakukan pengetikan dinamis, tipe pengembalian dapat berubah. Perhatikan bagaimana contoh mengembalikan skalar, daftar atau tuple ... apa pun yang Anda suka!

1-ijk
sumber
2

Jika ini adalah fungsi yang Anda gunakan sepanjang waktu tetapi selalu membuang argumen kedua, saya berpendapat bahwa itu kurang berantakan untuk membuat alias untuk fungsi tanpa menggunakan nilai balik kedua menggunakan lambda.

def func():
    return 1, 2

func_ = lambda: func()[0] 

func_()  # Prints 1 
Chrigi
sumber
2

Ketika Anda memiliki banyak output dari suatu fungsi dan Anda tidak ingin menyebutnya berkali-kali, saya pikir cara paling jelas untuk memilih hasilnya adalah:

results = fct()
a,b = [results[i] for i in list_of_index]

Sebagai contoh kerja minimum, juga menunjukkan bahwa fungsi ini dipanggil hanya sekali:

def fct(a):
    b=a*2
    c=a+2
    d=a+b
    e=b*2
    f=a*a
    print("fct called")
    return[a,b,c,d,e,f]

results=fct(3)
> fct called

x,y = [results[i] for i in [1,4]]

Dan nilainya seperti yang diharapkan:

results
> [3,6,5,9,12,9]
x
> 6
y
> 12

Untuk kenyamanan, indeks daftar Python juga dapat digunakan:

x,y = [results[i] for i in [0,-2]]

Pengembalian: a = 3 dan b = 12

jeannej
sumber