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.