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


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

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


الرمز \ في السلسلة العادية له معنى خاص. \t هو حرف علامة تبويب ، \r هو حرف إرجاع وهكذا.

يمكنك استخدام السلاسل الأولية لتعطيل هذا السلوك. r'\t' مجرد رد فعل مائل و t .

من الواضح أنك لا تستطيع استخدام ' الداخل r'...' . ومع ذلك ، لا يزال بالإمكان تخطيها بواسطة \ ، ولكن \ يتم الاحتفاظ بها في السلسلة:

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


قد تحتوي قائمة الاستيعاب على أكثر من واحدة for if الجمل:

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

أيضًا ، أي تعبير داخل و if قد يستخدم كافة المتغيرات التي تم تعريفها من قبل:

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

يمكنك الاختلاط if s و for s لكنك تريد:

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


تتيح لك الوظيفة sorted توفير طريقة مخصصة للفرز. يتم ذلك باستخدام الوسيطة key ، والتي توضح كيفية تحويل القيم الأصلية إلى قيم تتم مقارنتها فعليًا:

 >>> 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'}] 

للأسف ، ليست كل المكتبات التي تعمل مع المقارنة تدعم شيئًا ما مثل هذه الوسيطة key . الأمثلة البارزة هي heapq (الدعم الجزئي) heapq (لا يوجد دعم).

هناك طريقتان للتعامل مع الموقف. الأول هو استخدام الكائنات المخصصة التي تدعم الترميز المناسب:

 >>> 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'] 

ومع ذلك ، قد تضطر إلى إنشاء عدة إصدارات من هذه الفئات لأن هناك أكثر من طريقة لمقارنة الكائنات. يمكن أن تكون مرهقة ، ولكن يمكن حلها بسهولة بالطريقة الثانية.

بدلاً من إنشاء كائنات مخصصة ، يمكنك استخدام tuples (a, b) حيث a هي القيمة للمقارنة (تُعرف أيضًا باسم prioirty) و b هي القيمة الأصلية:

 >>> 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'] 


الفرق بين تعريف الوظيفة وتعريف المولد هو وجود الكلمة المفتاحية في نص الدالة:

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

هذا يعني أنه من أجل إنشاء مولد فارغ ، عليك القيام بشيء من هذا القبيل:

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

ومع ذلك ، نظرًا لأن yield from يدعم التكرارات البسيطة التي من الأفضل أن تكون النسخة ذات الشكل التالي:

 def g(): yield from [] 


في Python ، يمكنك سلسلة عوامل المقارنة:

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

لا يجب أن تكون هذه السلاسل صالحة رياضيا ، يمكنك المزج > و < :

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

عوامل التشغيل الأخرى مثل == ، يتم دعمها وفيها أيضًا:

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

يتم تطبيق كل عامل على أقرب اثنين من المعاملات. a OP1 b OP2 c تساوي تمامًا (a OP1 b) AND (b OP2 c) . لا توجد مقارنة بين a و c :

 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) 

الإخراج:

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

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


All Articles