Saya menggunakan Python max
dan min
fungsi pada daftar untuk algoritma minimax, dan saya perlu indeks dari nilai yang dikembalikan oleh max()
atau min()
. Dengan kata lain, saya perlu tahu langkah mana yang menghasilkan nilai maks (pada giliran pemain pertama) atau min (pemain kedua).
for i in range(9):
newBoard = currentBoard.newBoardWithMove([i / 3, i % 3], player)
if newBoard:
temp = minMax(newBoard, depth + 1, not isMinLevel)
values.append(temp)
if isMinLevel:
return min(values)
else:
return max(values)
Saya harus dapat mengembalikan indeks aktual nilai min atau maks, bukan hanya nilai.
divmod
ada untuk mencegah harus[i / 3, i % 3]
banyak bicara .Jawaban:
sumber
tmp = min(values); return values.index(tmp)
Katakan bahwa Anda memiliki daftar
values = [3,6,1,5]
, dan perlu indeks elemen terkecil, yaituindex_min = 2
dalam hal ini.Hindari solusi dengan
itemgetter()
disajikan dalam jawaban lain, dan gunakan sebaliknyakarena tidak perlu
import operator
atau tidak digunakanenumerate
, dan selalu lebih cepat (patokan di bawah) daripada menggunakan solusiitemgetter()
.Jika Anda berurusan dengan array numpy atau mampu
numpy
sebagai ketergantungan, pertimbangkan juga untuk menggunakannyaIni akan lebih cepat daripada solusi pertama bahkan jika Anda menerapkannya ke daftar Python murni jika:
numpy
arrayseperti yang ditunjukkan oleh tolok ukur ini:
Saya telah menjalankan benchmark pada mesin saya dengan python 2.7 untuk dua solusi di atas (biru: python murni, solusi pertama) (merah, solusi numpy) dan untuk solusi standar berdasarkan
itemgetter()
(hitam, solusi referensi). Patokan yang sama dengan python 3.5 menunjukkan bahwa metode membandingkan persis sama dari kasus python 2.7 yang disajikan di atassumber
xrange()
sekarang sudah tidak digunakan lagi, Anda dapat menggunakanrange()
import numpy as np; x = [2.3, -1.4]; np.argmin(x)
. Anda akan melihat bahwa itu jugaargmin
berfungsi pada floatAnda dapat menemukan indeks min / maks dan nilai pada saat yang sama jika Anda menghitung item dalam daftar, tetapi melakukan min / maks pada nilai-nilai asli daftar. Seperti itu:
Dengan cara ini daftar hanya akan dilintasi satu kali untuk min (atau maks).
sumber
key=lambda p: p[1]
Jika Anda ingin menemukan indeks max dalam daftar angka (yang tampaknya seperti kasus Anda), maka saya sarankan Anda menggunakan numpy:
sumber
Mungkin solusi yang lebih sederhana adalah mengubah array nilai menjadi array nilai, pasangan indeks, dan mengambil maks / min dari itu. Ini akan memberikan indeks terbesar / terkecil yang memiliki max / min (yaitu pasangan dibandingkan dengan terlebih dahulu membandingkan elemen pertama, dan kemudian membandingkan elemen kedua jika yang pertama adalah sama). Perhatikan bahwa tidak perlu untuk benar-benar membuat array, karena min / max memungkinkan generator sebagai input.
sumber
Akan memberi Anda indeks minimum pertama.
sumber
Saya pikir hal terbaik untuk dilakukan adalah mengonversi daftar menjadi a
numpy array
dan menggunakan fungsi ini:sumber
Saya juga tertarik dengan ini dan membandingkan beberapa solusi yang disarankan menggunakan perfplot (proyek kesayangan saya).
Ternyata argmin numpy itu ,
adalah metode tercepat untuk daftar yang cukup besar, bahkan dengan konversi implisit dari input
list
ke anumpy.array
.Kode untuk menghasilkan plot:
sumber
Gunakan array numpy dan fungsi argmax ()
sumber
Setelah Anda mendapatkan nilai maksimum, coba ini:
Jauh lebih sederhana daripada banyak opsi.
sumber
Saya pikir jawaban di atas menyelesaikan masalah Anda, tetapi saya pikir saya akan membagikan metode yang memberi Anda minimum dan semua indeks minimum muncul.
Ini melewati daftar dua kali tetapi masih cukup cepat. Namun itu sedikit lebih lambat daripada menemukan indeks pertemuan pertama minimum. Jadi, jika Anda hanya membutuhkan satu dari minimum, gunakan solusi Matt Anderson , jika Anda membutuhkan semuanya, gunakan ini.
sumber
Gunakan fungsi modul numpy numpy.where
Untuk indeks nilai minimum:
Untuk indeks nilai maksimum:
Bahkan, fungsi ini jauh lebih kuat. Anda dapat mengajukan semua jenis operasi boolean Untuk indeks nilai antara 3 dan 60:
sumber
argmin()
daripada apa yang Anda lakukan di sini.Ini sangat mungkin menggunakan built-in
enumerate()
danmax()
fungsi sertakey
argumen opsionalmax()
fungsi dan ekspresi lambda sederhana:Dalam dokumen untuk
max()
itu dikatakan bahwakey
argumen mengharapkan fungsi seperti dalamlist.sort()
fungsi. Lihat juga Cara Menyortir .Ini berfungsi sama untuk
min()
. Btw mengembalikan nilai max / min pertama.sumber
Katakanlah Anda memiliki daftar seperti:
Dua metode berikut adalah cara yang cukup ringkas untuk mendapatkan tuple dengan elemen minimum dan indeksnya. Keduanya membutuhkan waktu yang sama untuk diproses. Saya lebih suka metode zip, tapi itu selera saya.
metode zip
menghitung metode
sumber
Selama Anda tahu cara menggunakan lambda dan argumen "kunci", solusi sederhana adalah:
sumber
n
itu bisa terasa lebih lambat.Sederhana seperti itu :
sumber
Mengapa repot-repot menambahkan indeks terlebih dahulu dan kemudian membalikkannya? Enumerate () function hanyalah kasus khusus dari penggunaan fungsi zip (). Mari kita gunakan dengan cara yang tepat:
sumber
Hanya tambahan kecil dari apa yang telah dikatakan.
values.index(min(values))
tampaknya mengembalikan indeks min terkecil. Berikut ini mendapatkan indeks terbesar:Baris terakhir dapat ditinggalkan jika efek samping dari pembalikan di tempat tidak masalah.
Untuk mengulangi semua kejadian
Demi singkatnya. Mungkin ide yang lebih baik untuk melakukan cache di
min(values), values.count(min)
luar loop.sumber
reversed(…)
bukannya….reverse()
lebih disukai karena tidak bermutasi dan mengembalikan generator. Dan semua kejadian juga bisaminv = min(values); indices = [i for i, v in enumerate(values) if v == minv]
Cara mudah untuk menemukan indeks dengan nilai minimal dalam daftar jika Anda tidak ingin mengimpor modul tambahan:
Kemudian pilih misalnya yang pertama:
sumber
Jangan punya rep yang cukup tinggi untuk mengomentari jawaban yang ada.
Tetapi untuk https://stackoverflow.com/a/11825864/3920439 jawabannya
Ini berfungsi untuk bilangan bulat, tetapi tidak berfungsi untuk array float (setidaknya dalam python 3.6) Ini akan naik
TypeError: list indices must be integers or slices, not float
sumber
https://docs.python.org/3/library/functions.html#max
Jika beberapa item maksimal, fungsi mengembalikan item pertama yang ditemui. Ini konsisten dengan alat pengawet semacam stabilitas seperti
sorted(iterable, key=keyfunc, reverse=True)[0]
Untuk mendapatkan lebih dari sekedar yang pertama, gunakan metode sortir.
sumber
Bagaimana dengan ini:
Itu membuat kamus dari item dalam
a
sebagai kunci dan indeks mereka sebagai nilai, sehinggadict(zip(a,range(len(a))))[max(a)]
mengembalikan nilai yang sesuai dengan kuncimax(a)
yang merupakan indeks maksimum dalam. Saya seorang pemula dalam python jadi saya tidak tahu tentang kompleksitas komputasi dari solusi ini.sumber