python - أفضل طريقة للعثور على تقاطع مجموعات متعددة؟




set set-intersection (5)

لدي قائمة بالمجموعات:

setlist = [s1,s2,s3...]

اريد s1 ∩ s2 ∩ s3 ...

يمكنني كتابة وظيفة للقيام بذلك عن طريق تنفيذ سلسلة من s1.intersection(s2) ، إلخ.

هل هناك طريقة موصى بها أو أفضل أو مدمجة؟


Answers

إذا لم يكن لديك Python 2.6 أو أعلى ، فسيكون البديل كتابة حلقة صريحة للحلقة:

def set_list_intersection(set_list):
  if not set_list:
    return set()
  result = set_list[0]
  for s in set_list[1:]:
    result &= s
  return result

set_list = [set([1, 2]), set([1, 3]), set([1, 4])]
print set_list_intersection(set_list)
# Output: set([1])

يمكنك أيضًا استخدام reduce :

set_list = [set([1, 2]), set([1, 3]), set([1, 4])]
print reduce(lambda s1, s2: s1 & s2, set_list)
# Output: set([1])

ومع ذلك ، فإن العديد من المبرمجين في بيثون لا يحبونها ، بما في ذلك غيدو نفسه :

منذ حوالي 12 عامًا ، كانت بيثون تتزود بامدا ، وتخفّض () ، وفلتر () وخريطة () ، من باب المجاملة (على ما أظن) أحد المتسلّلين من ليسب الذين غاب عنهم وقدموا بقع عمل. ولكن ، على الرغم من قيمة العلاقات العامة ، أعتقد أنه يجب قطع هذه الميزات من Python 3000.

حتى الآن تقلل (). هذا في الواقع هو ما أكرهه دائماً ، لأنه بخلاف بعض الأمثلة التي تتضمن + أو * ، في كل مرة أرى فيها مكالمة () أقل تقريبًا مع حجة دالة غير عادية ، أحتاج إلى إمساك القلم والورقة الرسم البياني ما يتم إدخاله بالفعل في هذه الوظيفة قبل أن أفهم ما الذي يفترض أن تقوم به. لذا في رأيي ، فإن قابلية التقليل () تقصر إلى حد كبير على المشغلين التابعين ، وفي جميع الحالات الأخرى من الأفضل كتابة حلقة التراكم بشكل واضح.


هنا ، أقدم وظيفة عامة للتقاطع المتعدد في محاولة للاستفادة من أفضل الطرق المتاحة:

def multiple_set_intersection(*sets):
    """Return multiple set intersection."""
    try:
        return set.intersection(*sets)
    except TypeError: # this is Python < 2.6 or no arguments
        pass

    try: a_set= sets[0]
    except IndexError: # no arguments
        return set() # return empty set

    return reduce(a_set.intersection, sets[1:])

Guido قد يكره reduce ، ولكن أنا من النوع مغرم :)


من Python الإصدار 2.6 يمكنك استخدام وسائط متعددة ل set.intersection() ، مثل

u = set.intersection(s1, s2, s3)

إذا كانت المجموعات في قائمة ، فسيتم ترجمة ذلك إلى:

u = set.intersection(*setlist)

حيث *a_list هو توسيع قائمة


من الواضح أن set.intersection هو ما تريده هنا ، ولكن إذا احتجت في أي وقت إلى تعميم "خذ مجموع كل هذه" ، "أخذ منتج كل هذه" ، "خذ xor من كل هذه" ، ما الذي تبحث عنه reduce وظيفة:

from operator import and_
from functools import reduce
print(reduce(and_, [{1,2,3},{2,3,4},{3,4,5}])) # = {3}

أو

print(reduce((lambda x,y: x&y), [{1,2,3},{2,3,4},{3,4,5}])) # = {3}

هناك عدة طرق لاستخدام Python على Android.

BeeWare عبارة عن مجموعة من الأدوات لبناء واجهات المستخدم الأصلية

Chaquopy هو مكون إضافي لنظام البناء القائم على Gradle المستند إلى Android Studio.

Kivy عبارة عن مجموعة أدوات واجهة المستخدم المستندة إلى OpenGL عبر النظام الأساسي.

pyqtdeploy هو أداة لنشر تطبيقات PyQt.

QPython هو مشغل البرامج النصية على الجهاز وبيئة التطوير.

SL4A (Scripting Layer for Android) ، التي تم تسميتها أصلاً ASE (Android Scripting Environment) ، هي عبارة عن مجموعة من "الواجهات" التي تعرض مجموعة فرعية مبسطة جدًا من واجهة برمجة تطبيقات Android.

PySide (ملزمة Python لمجموعة أدوات Qt) على بعض الدعم المبدئي لنظام Android.

على الرغم من أن لغة البرمجة الأساسية في Android هي Java ، فلا يوجد منفذ معروف من Jython إلى النظام الأساسي. يتم تحقيق دعم Android في BeeWare باستخدام VOC ، وهي أداة تجمع شفرة Python المصدر إلى ملفات فئة Java. يسمح هذا بتنفيذ Python كبرنامج ثنائي محلي على JVM. https://wiki.python.org/moin/Android





python set set-intersection