Python3 sorted函数中key参数的作用原理
高洛峰
高洛峰 2017-04-17 17:47:14
0
3
1486

这是一个字符串排序,排序规则:小写<大写<奇数<偶数

s = 'asdf234GDSdsf23'  #排序:小写-大写-奇数-偶数
print("".join(sorted(s, key=lambda x: (x.isdigit(), x.isdigit() and int(x) % 2 == 0, x.isupper(), x.islower(), x))))

这里key接受的函数返回的是一个元组?是如何进行比较的?

高洛峰
高洛峰

拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

membalas semua(3)
伊谢尔伦

Bandingkan nilai pertama tuple dahulu, FALSE<TRUE, jika sama, bandingkan nilai tuple seterusnya dan seterusnya.

洪涛

Mari kita mulakan dengan contoh mudah:

items = [(1, 2), (2, 1)]
print(sorted(items))

Keputusan:

[(1, 2), (2, 1)]

items ialah senarai tupel jika diisih, fungsi Builtin Python sorted (atau sort) akan mengisih daripada elemen terakhir tuple, iaitu, satu set dua elemen tupel boleh dibayangkan sebagai dua pengisihan asas:

Asalnya:

[(2, 1), (1, 2)]

Isihan pertama menggunakan elemen kedua sebagai kunci, jadi hasil isihan ialah:

[(2, 1), (1, 2)]

Isihan kedua menggunakan elemen pertama sebagai kunci, jadi hasil isihan ialah:

[(1, 2), (2, 1)] # 最終結果

Kesimpulan (1):

Pengisihan tupel diisih dari elemen terakhir ke hadapan
Maksudnya, berat pengisihan tupel bermula dari elemen pertama dan berkurangan ke belakang


Kemudian mari kita perhatikan pengisihan nilai Boolean:

print(sorted([True, False])

Keputusan:

[False, True] # False在前,True在後

Kesimpulan 2:

Isihan Boolean akan meletakkan False di hadapan dan True di bahagian bawah


Kemudian mari kita lihat contoh yang anda berikan Mari tulis fungsi mudah untuk memerhatikan hasilnya:

def show(s):
    for x in s:
        print((x.isdigit(), x.isdigit() and int(x)%2==0, x.isupper(), x.islower(), x))

fungsi show akan mencetak rentetan semasa s yang digunakan untuk menjana kunci tuple bagi setiap aksara semasa pengisihan.

Kemudian kami menggunakan kesimpulan 1 tadi Daripada menggunakan tuple sebagai kunci, kami menggunakan yang setara untuk mengisih kunci dari elemen terakhir ke hadapan , dan amati perubahan s dan tuple secara beransur-ansur. dalam kunci:

print('key=x')
s = sorted(s ,key=lambda x: x)
show(s)

print('key=islower()')
s = sorted(s ,key=lambda x: x.islower())
show(s)

print('key=isupper()')
s = sorted(s ,key=lambda x: x.isupper())
show(s)

print('key=isdigit() and int(x)%2==0')
s = sorted(s ,key=lambda x: x.isdigit() and int(x)%2==0)
show(s)

Kami akan mendapati bahawa, seperti yang dijangkakan, mengikut kesimpulan (1), pendekatan ini sememangnya setara dengan mengisih dengan tuple sebagai kunci sekali gus.
Perhatikan pada masa yang sama, kesimpulan (2), untuk kekunci Boolean yang dijana oleh isdigit(), isupper(), islower(), dsb., hasil pengisihan juga seperti yang dijangkakan.

print('key=isdigit()')
s = sorted(s ,key=lambda x: x.isdigit())
show(s)

Tetapi saya rasa ini bukan kesimpulan terakhir kami, kerana ia adalah hasil kebetulan (mungkin terlalu banyak untuk mengatakan ia berlaku, ia harus dikatakan sebagai hasil yang kurang intuitif), mari kita simpulkan berdasarkan Kesimpulan (1) Analisis contoh asal:

sorted(s, key=lambda x: (x.isdigit(), x.isdigit() and int(x) % 2 == 0, x.isupper(), x.islower(), x))

Kita boleh menterjemahkan pengisihan ini kepada:

Mula-mula susun aksara x itu sendiri, dan kemudian susun sama ada aksara itu huruf kecil, sama ada aksara itu huruf besar, sama ada aksara itu nombor genap dan sama ada aksara itu nombor.

juga boleh diterjemahkan sebagai:

Kami menggunakan sama ada aksara ialah nombor sebagai berat pengisihan tertinggi, dan kemudian kami menggunakan sama ada aksara itu nombor genap, sama ada aksara itu huruf besar, sama ada aksara itu huruf kecil dan aksara x itu sendiri sebagai beratnya.

Ini nampaknya berbeza daripada matlamat awal (#Sort: huruf kecil-huruf besar-ganjil-genap), sekurang-kurangnya ia tidak mempunyai korespondensi intuitif dengan matlamat.

Adalah disyorkan untuk menukarnya kepada:

print("".join(sorted(s1, key=lambda x: (not x.islower(), not x.isupper(), not(x.isdigit() and int(x)%2==1), x))))

Ini boleh ditafsirkan sebagai:

Kami menggunakan sama ada aksara itu huruf kecil sebagai pemberat tertinggi, dan kemudian menggunakan sama ada aksara itu huruf besar, sama ada aksara itu nombor ganjil, dan aksara x itu sendiri sebagai pemberat untuk diisih

Perkara yang menarik ialah: kami mahu watak-watak yang formula penghakimannya True dibandingkan dengan kedudukan sebelumnya selepas pengisihan selesai, jadi berdasarkan kesimpulan (2), kami menambah not supaya padanan aksara boleh berada di Hadapan.

小葫芦

Intinya adalah seperti yang donghui berkata, SALAH<BENAR.
kunci ialah situasi pengisihan bagi tuple Setiap elemen yang akan diisih menghasilkan satu tuple (x.isdigit(), x.isdigit() and int(x) % 2 == 0, x.isupper(), x.islower(), x) Asasnya adalah FALSE<TRUE, false diletakkan di kedudukan pertama, dan true dinobatkan sebagai yang terakhir mereka adalah sama, Lihat seterusnya. disusun akhirnya mengembalikan unsur-unsur yang perlu diisih.

Kod ujian adalah seperti berikut: (dari dokelung dan donghui)

if __name__ == '__main__':
    s = 'asdf234GDSdsf23'

    print('key=x')
    s = sorted(s, key=lambda x: x)
    for x in s:
        print((x, x))

    print('key=islower()')
    s = sorted(s, key=lambda x: x.islower())
    for x in s:
        print((x.islower(), x))

    print('key=isupper()')
    s = sorted(s, key=lambda x: x.isupper())
    for x in s:
        print((x.isupper(), x))

    print('key=isdigit() and int(x)%2==0')
    s = sorted(s, key=lambda x: x.isdigit() and int(x) % 2 == 0)
    for x in s:
        print((x.isdigit() and int(x) % 2 == 0, x))

    print('key=(x.isupper(), x.islower())')
    s = sorted(s, key=lambda x: (x.isupper(), x.islower()))
    for x in s:
        print((x.isupper(), x.islower(), x))

    print('key=(x.isdigit(), x.isdigit() and int(x) % 2 == 0, x.isupper(), x.islower(), x))')
    s = sorted(s, key=lambda x: (x.isdigit(), x.isdigit() and int(x) % 2 == 0, x.isupper(), x.islower(), x))
    for x in s:
        print((x.isdigit(), x.isdigit() and int(x) % 2 == 0, x.isupper(), x.islower(), x))

Jalankan dan lihat input untuk menemui corak.
Output:

key=x
('2', '2')
('2', '2')
('3', '3')
('3', '3')
('4', '4')
('D', 'D')
('G', 'G')
('S', 'S')
('a', 'a')
('d', 'd')
('d', 'd')
('f', 'f')
('f', 'f')
('s', 's')
('s', 's')
key=islower()
(False, '2')
(False, '2')
(False, '3')
(False, '3')
(False, '4')
(False, 'D')
(False, 'G')
(False, 'S')
(True, 'a')
(True, 'd')
(True, 'd')
(True, 'f')
(True, 'f')
(True, 's')
(True, 's')
key=isupper()
(False, '2')
(False, '2')
(False, '3')
(False, '3')
(False, '4')
(False, 'a')
(False, 'd')
(False, 'd')
(False, 'f')
(False, 'f')
(False, 's')
(False, 's')
(True, 'D')
(True, 'G')
(True, 'S')
key=isdigit() and int(x)%2==0
(False, '3')
(False, '3')
(False, 'a')
(False, 'd')
(False, 'd')
(False, 'f')
(False, 'f')
(False, 's')
(False, 's')
(False, 'D')
(False, 'G')
(False, 'S')
(True, '2')
(True, '2')
(True, '4')
key=(x.isupper(), x.islower())
(False, False, '3')
(False, False, '3')
(False, False, '2')
(False, False, '2')
(False, False, '4')
(False, True, 'a')
(False, True, 'd')
(False, True, 'd')
(False, True, 'f')
(False, True, 'f')
(False, True, 's')
(False, True, 's')
(True, False, 'D')
(True, False, 'G')
(True, False, 'S')
key=(x.isdigit(), x.isdigit() and int(x) % 2 == 0, x.isupper(), x.islower(), x))
(False, False, False, True, 'a')
(False, False, False, True, 'd')
(False, False, False, True, 'd')
(False, False, False, True, 'f')
(False, False, False, True, 'f')
(False, False, False, True, 's')
(False, False, False, True, 's')
(False, False, True, False, 'D')
(False, False, True, False, 'G')
(False, False, True, False, 'S')
(True, False, False, False, '3')
(True, False, False, False, '3')
(True, True, False, False, '2')
(True, True, False, False, '2')
(True, True, False, False, '4')
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan