@Pythonetc Juni 2019


Ini adalah pilihan tips dan pemrograman Python kesebelas dari feed @pythonetc saya.

โ† Koleksi sebelumnya


Karakter \ pada baris reguler memiliki arti khusus. \t adalah karakter tab, \r adalah break baris, dan sebagainya.

Untuk menonaktifkan perilaku ini, Anda dapat menggunakan string mentah. Kemudian r'\t' akan berubah menjadi hanya garis miring terbalik dan t .

Jelas, Anda tidak dapat menggunakan ' inside r'...' . Dan meskipun pembatasan ini dapat dielakkan dengan \ , namun, garis \ akan tetap:

 >>> print(r'It\'s insane!') It\'s insane! 


Daftar generator dapat berisi lebih dari satu pasang for dan if ekspresi:

 In : [(x, y) for x in range(3) for y in range(3)] Out: [ (0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2) ] In : [ (x, y) for x in range(3) for y in range(3) if x != 0 if y != 0 ] Out: [(1, 1), (1, 2), (2, 1), (2, 2)] 

Selain itu, ekspresi apa pun di dalam for dan if dapat menggunakan semua variabel yang ditentukan sebelumnya:

 In : [ (x, y) for x in range(3) for y in range(x + 2) if x != y ] Out: [ (0, 1), (1, 0), (1, 2), (2, 0), (2, 1), (2, 3) ] 

Anda dapat mencampur if dan sesuai keinginan:

 In : [ (x, y) for x in range(5) if x % 2 for y in range(x + 2) if x != y ] Out: [ (1, 0), (1, 2), (3, 0), (3, 1), (3, 2), (3, 4) ] 


Fungsi yang sorted memungkinkan sorted menentukan metode penyortiran khusus. Ini dilakukan dengan menggunakan argumen key , yang menjelaskan cara mengonversi nilai asli untuk perbandingan nanti:

 >>> x = [dict(name='Vadim', age=29), dict(name='Alex', age=4)] >>> sorted(x, key=lambda v: v['age']) [{'age': 4, 'name': 'Alex'}, {'age': 29, 'name': 'Vadim'}] 

Sayangnya, tidak semua perpustakaan yang bekerja dengan perbandingan mendukung argumen key . Dari mereka yang dikabarkan, heapq (dukungan parsial) dan bisect (tidak ada dukungan) dapat disebutkan.

Ada dua cara untuk dilakukan dalam situasi ini. Anda dapat menggunakan objek khusus yang mendukung perbandingan yang tepat:

 >>> class User: ... def __init__(self, name, age): ... self.name = name ... self.age = age ... def __lt__(self, other): ... return self.age < other.age ... >>> x = [User('Vadim', 29), User('Alex', 4)] >>> [x.name for x in sorted(x)] ['Alex', 'Vadim'] 

Namun, Anda mungkin perlu membuat beberapa versi kelas seperti itu, karena objek dapat dibandingkan dengan cara yang berbeda. Ini bisa merepotkan, jadi ada cara kedua.

Alih-alih membuat objek khusus, Anda dapat menggunakan tupel (a, b) , di mana a adalah nilai untuk membandingkan (prioritas), dan b adalah nilai asli:

 >>> users = [dict(name='Vadim', age=29), dict(name='Alex', age=4)] >>> to_sort = [(u['age'], u) for u in users] >>> [x[1]['name'] for x in sorted(to_sort)] ['Alex', 'Vadim'] 


Perbedaan antara definisi dan fungsi generator adalah adanya kata kunci yield di badan fungsi:

 In : def f(): ...: pass ...: In : def g(): ...: yield ...: In : type(f()) Out: NoneType In : type(g()) Out: generator 

Ini berarti bahwa untuk membuat generator kosong Anda perlu melakukan ini:

 In : def g(): ...: if False: ...: yield ...: In : list(g()) Out: [] 

Tetapi karena yield from dukungan iterators sederhana, yaitu versi yang lebih bagus:

 def g(): yield from [] 


Dengan Python, Anda dapat membuat rantai operator perbandingan:

 >>> 0 < 1 < 2 True >>> 0 < 1 < 0 False 

Rantai seperti itu tidak harus benar secara matematis, Anda dapat mencampur > dan < :

 >>> 0 < 1 > 2 False >>> 0 < 1 < 2 > 1 > 0 True 

== operator juga didukung. is dan in :

 >>> [] is not 3 in [1, 2, 3] True 

Setiap operator berlaku untuk dua operan yang berdekatan. a OP1 b OP2 c benar a OP1 b OP2 c benar setara dengan (a OP1 b) AND (b OP2 c) . Perbandingan a dan c tidak dilakukan:

 class Spy: def __init__(self, x): self.x = x def __eq__(self, other): print(f'{self.x} == {other.x}') return self.x == other.x def __ne__(self, other): print(f'{self.x} != {other.x}') return self.x != other.x def __lt__(self, other): print(f'{self.x} < {other.x}') return self.x < other.x def __le__(self, other): print(f'{self.x} <= {other.x}') return self.x <= other.x def __gt__(self, other): print(f'{self.x} > {other.x}') return self.x > other.x def __ge__(self, other): print(f'{self.x} >= {other.x}') return self.x >= other.x s1 = Spy(1) s2 = Spy(2) s3 = Spy(3) print(s1 is s1 < s2 <= s3 == s3) 

Hasil:

 1 < 2 2 <= 3 3 == 3 True 

Source: https://habr.com/ru/post/id458686/


All Articles