[python] هل لدى بايثون مجموعة مرتبة؟


5 Answers

مجموعة مرتبة هي وظيفيا حالة خاصة من القاموس المرتب.

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

اعتبارا من بايثون 3.1 هناك collections.OrderedDict . فيما يلي مثال تنفيذ تطبيق OrderedSet. (لاحظ أن هناك طرق قليلة فقط تحتاج إلى تعريف أو تجاوز: collections.OrderedDict ومجموعات collections.MutableSet القيام بالرفع الثقيل.)

import collections

class OrderedSet(collections.OrderedDict, collections.MutableSet):

    def update(self, *args, **kwargs):
        if kwargs:
            raise TypeError("update() takes no keyword arguments")

        for s in args:
            for e in s:
                 self.add(e)

    def add(self, elem):
        self[elem] = None

    def discard(self, elem):
        self.pop(elem, None)

    def __le__(self, other):
        return all(e in other for e in self)

    def __lt__(self, other):
        return self <= other and self != other

    def __ge__(self, other):
        return all(e in self for e in other)

    def __gt__(self, other):
        return self >= other and self != other

    def __repr__(self):
        return 'OrderedSet([%s])' % (', '.join(map(repr, self.keys())))

    def __str__(self):
        return '{%s}' % (', '.join(map(repr, self.keys())))

    difference = property(lambda self: self.__sub__)
    difference_update = property(lambda self: self.__isub__)
    intersection = property(lambda self: self.__and__)
    intersection_update = property(lambda self: self.__iand__)
    issubset = property(lambda self: self.__le__)
    issuperset = property(lambda self: self.__ge__)
    symmetric_difference = property(lambda self: self.__xor__)
    symmetric_difference_update = property(lambda self: self.__ixor__)
    union = property(lambda self: self.__or__)
Question

لدى Python قاموس مرتب . ماذا عن مجموعة مرتبة؟




تأخرت قليلاً في اللعبة ، ولكني كتبت setlist صفوف كجزء من collections-extended التي تنفذ كلاً من Sequence

>>> from collections_extended import setlist
>>> sl = setlist('abracadabra')
>>> sl
setlist(('a', 'b', 'r', 'c', 'd'))
>>> sl[3]
'c'
>>> sl[-1]
'd'
>>> 'r' in sl  # testing for inclusion is fast
True
>>> sl.index('d')  # so is finding the index of an element
4
>>> sl.insert(1, 'd')  # inserting an element already in raises a ValueError
ValueError
>>> sl.index('d')
4

GitHub: https://github.com/mlenzen/collections-extended

الوثائق: http://collections-extended.lenzm.net/en/latest/

PyPI: https://pypi.python.org/pypi/collections-extended




لا يوجد OrderedSet في المكتبة الرسمية. أقوم بعمل chitesheet شاملة لجميع هيكل البيانات للرجوع اليها.

DataStructure = {'Collections': {'Map': [('dict', 'OrderDict', 'defaultdict'),
                                         ('chainmap', 'types.MappingProxyType')],
                                 'Set': [('set', 'frozenset'), {'multiset':'collection.Counter'}]},
                                 'Sequence': {'Basic': ['list', 'tuple', 'iterator']},
                                              'Algorithm': {'Priority': ['heapq',
                                                                         'queue.PriorityQueue'],
                                                            'Queue': ['queue.Queue',
                                                                      'multiprocessing.Queue'],
                                                            'Stack': ['collection.deque',
                                                                      'queue.LifeQueue']},
                 'text_sequence': ['str', 'byte', 'bytearray']}



لكثير من الأغراض ، يكفي أن يتم فرز المكالمات. فمثلا

>>> s = set([0, 1, 2, 99, 4, 40, 3, 20, 24, 100, 60])
>>> sorted(s)
[0, 1, 2, 3, 4, 20, 24, 40, 60, 99, 100]

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




يمكنك استخدام reduce() للحصول على قائمة بالقيم الفريدة في سطر واحد:

>>> mylist = [4, 1, 2, 1, 3, 2, 4, 1, 3, 2, 3, 1, 3, 2, 4]
>>> reduce(lambda a, b: b[0] in a and a or a + b, [[i] for i in mylist])
[4, 1, 2, 3]



يمكنني أن أفعل لك أفضل واحد من OrderedSet: يحتوي boltons على نوع IndexedSet نقي بيثون 2/3-متوافق ليس فقط مجموعة مرتبة ، ولكنه يدعم أيضًا الفهرسة (كما هو الحال مع القوائم).

ببساطة pip install boltons (أو قم بنسخ setutils.py في تعليمات البرمجة لديك) ، IndexedSet باستيراد IndexedSet و:

>>> x = IndexedSet(list(range(4)) + list(range(8)))
>>> x
IndexedSet([0, 1, 2, 3, 4, 5, 6, 7])
>>> x - set(range(2))
IndexedSet([2, 3, 4, 5, 6, 7])
>>> x[-1]
7
>>> fcr = IndexedSet('freecreditreport.com')
>>> ''.join(fcr[:fcr.index('.')])
'frecditpo'

كل شيء فريد واحتفظ بالترتيب. الإفصاح الكامل: كتبت " IndexedSet ، ولكن هذا يعني أيضًا أنه يمكنك أن IndexedSet إذا كانت هناك أية مشكلات . :)




Related



Tags

python python   set