Kiat dan trik dari saluran Telegram saya @pythonetc, Maret 2019

gambar

Ini adalah pilihan baru tips dan trik tentang Python dan pemrograman dari saluran-Telegram saya @pythonetc.

Publikasi sebelumnya .

0_0


0_0 adalah ekspresi Python yang benar-benar valid.

Menyortir daftar dengan Tidak Ada


Menyortir daftar dengan Nilai tidak None bisa jadi menantang:

 In [1]: data = [ ...: dict(a=1), ...: None, ...: dict(a=-3), ...: dict(a=2), ...: None, ...: ] In [2]: sorted(data, key=lambda x: x['a']) ... TypeError: 'NoneType' object is not subscriptable 

Anda dapat mencoba menghapus Nones dan mengembalikannya setelah pengurutan (ke akhir atau awal daftar tergantung pada tugas Anda):

 In [3]: sorted( ...: (d for d in data if d is not None), ...: key=lambda x: x['a'] ...: ) + [ ...: d for d in data if d is None ...: ] Out[3]: [{'a': -3}, {'a': 1}, {'a': 2}, None, None] 

Itu seteguk. Solusi yang lebih baik adalah dengan menggunakan key yang lebih kompleks:

 In [4]: sorted(data, key=lambda x: float('inf') if x is None else x['a']) Out[4]: [{'a': -3}, {'a': 1}, {'a': 2}, None, None] 

Untuk jenis yang tidak tersedia tanpa batas, Anda dapat mengurutkan tuple sebagai gantinya:

 In [5]: sorted(data, key=lambda x: (1, None) if x is None else (0, x['a'])) Out[5]: [{'a': -3}, {'a': 1}, {'a': 2}, None, None] 

Memanggil random.seed ()


Saat Anda memotong proses Anda, seed acak yang Anda gunakan menyalin seluruh proses. Itu dapat menyebabkan proses yang menghasilkan hasil "acak" yang sama.

Untuk menghindari ini, Anda harus secara manual memanggil random.seed() dalam setiap proses.

Namun, itu tidak terjadi jika Anda menggunakan modul multiprocessing , ia melakukan hal itu untuk Anda.

Berikut ini sebuah contoh:

 import multiprocessing import random import os import sys def test(a): print(random.choice(a), end=' ') a = [1, 2, 3, 4, 5] for _ in range(5): test(a) print() for _ in range(5): p = multiprocessing.Process( target=test, args=(a,) ) p.start() p.join() print() for _ in range(5): pid = os.fork() if pid == 0: test(a) sys.exit() else: os.wait() print() 

Hasilnya adalah seperti:

 4 4 4 5 5 1 4 1 3 3 2 2 2 2 2 

Selain itu, jika Anda menggunakan Python 3.7 atau yang lebih baru, os.fork melakukan hal yang sama, terima kasih kepada at_fork hook baru.

Output dari kode di atas untuk Python 3.7 adalah:

 1 2 2 1 5 4 4 4 5 5 2 4 1 3 1 

Menambahkan ke 0


Sepertinya sum([a, b, c]) setara a + b + c , padahal sebenarnya 0 + a + b + c . Itu berarti tidak dapat bekerja dengan tipe yang tidak mendukung penambahan ke 0 :

 class MyInt: def __init__(self, value): self.value = value def __add__(self, other): return type(self)(self.value + other.value) def __radd__(self, other): return self + other def __repr__(self): class_name = type(self).__name__ return f'{class_name}({self.value})' In : sum([MyInt(1), MyInt(2)]) ... AttributeError: 'int' object has no attribute 'value' 

Untuk memperbaikinya Anda dapat memberikan elemen mulai kustom yang digunakan alih-alih 0 :

 In : sum([MyInt(1), MyInt(2)], MyInt(0)) Out: MyInt(3) 

sum dioptimalkan dengan baik untuk penjumlahan tipe float dan int tetapi dapat menangani tipe kustom lainnya. Namun, ia menolak untuk menjumlahkan bytes , bytearray dan str karena join dioptimalkan dengan baik untuk operasi ini:

 In : sum(['a', 'b'], '') ... TypeError: sum() can't sum strings [use ''.join(seq) instead] In : ints = [x for x in range(10_000)] In : my_ints = [Int(x) for x in ints] In : %timeit sum(ints) 68.3 µs ± 142 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each) In : %timeit sum(my_ints, Int(0)) 5.81 ms ± 20.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 



Penyelesaian indeks dalam notebook jupyter


Anda dapat menyesuaikan penyelesaian indeks dalam buku catatan Jupyter dengan memberikan _ipython_key_completions_ method . Dengan cara ini Anda dapat mengontrol apa yang ditampilkan ketika Anda menekan tab setelah sesuatu seperti d["x :



Perhatikan bahwa metode ini tidak mendapatkan string yang dicari sebagai argumen.

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


All Articles