نصائح وحيل من my Telegram-channelpythonetc ، مارس 2019

صورة

إنها مجموعة جديدة من النصائح والحيل حول Python والبرمجة من قناة Telegram-channelpythonetc.

المنشورات السابقة .

0_0


0_0 تعبير Python صالح تمامًا.

فرز قائمة مع لا شيء


يمكن أن يمثل تصنيف قائمة بلا قيم تحديا:

 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 

يمكنك محاولة إزالة الأسماء ووضعها مرة أخرى بعد الفرز (إلى نهاية أو بداية القائمة حسب مهمتك):

 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] 

هذا الفم. الحل الأفضل هو استخدام key أكثر تعقيدًا:

 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] 

بالنسبة للأنواع التي لا تتوفر فيها اللانهاية ، يمكنك فرز المجموعات بدلاً من ذلك:

 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] 

الاتصال عشوائي. البذور ()


عندما تتفرع عن العملية الخاصة بك ، يتم نسخ البذور العشوائية التي تستخدمها عبر العمليات. قد يؤدي ذلك إلى عمليات تنتج نفس النتيجة "العشوائية".

لتجنب ذلك ، يجب عليك الاتصال random.seed() في كل عملية.

ومع ذلك ، ليس هذا هو الحال إذا كنت تستخدم وحدة multiprocessing ، فهي تفعل ذلك بالضبط بالنسبة لك.

هنا مثال:

 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() 

والنتيجة هي شيء مثل:

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

علاوة على ذلك ، إذا كنت تستخدم Python 3.7 أو الأحدث ، فإن os.fork يفعل نفس الشيء ، وذلك بفضل الخطاف الجديد at_fork .

إخراج الكود أعلاه لبيثون 3.7 هو:

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

إضافة إلى 0


يبدو أن sum([a, b, c]) مكافئة لـ a + b + c ، بينما في الحقيقة تكون 0 + a + b + c . هذا يعني أنه لا يمكنه العمل مع أنواع لا تدعم إضافة إلى 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' 

لإصلاح أنه يمكنك توفير عنصر بدء مخصص يُستخدم بدلاً من 0 :

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

تم تحسين sum بشكل جيد لتجميع أنواع float و int لكن يمكنه التعامل مع أي نوع مخصص آخر. ومع ذلك ، فإنه يرفض جمع bytes ، bytearray حيث إن bytearray تم تحسينها بشكل جيد لهذه العملية:

 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) 



اكتمال الفهرس في دفتر jupyter


يمكنك تخصيص اكتمال الفهرس في دفتر Jupyter من خلال توفير _ipython_key_completions_ method . وبهذه الطريقة يمكنك التحكم في ما يتم عرضه عند الضغط على علامة التبويب بعد شيء مثل d["x :



لاحظ أن الطريقة لا تحصل على سلسلة البحث كوسيطة.

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


All Articles