পাইথনের কি অর্ডার করা সেট আছে?


476

পাইথনের একটি অর্ডারযুক্ত অভিধান রয়েছে । একটি অর্ডার সেট সম্পর্কে কি?


18
কনভার্স, জিনিস একটি ব্যাগ সম্পর্কে কি? (আনর্ডারড এবং অ-অনন্য)
উইম

19
@ উইমটি collections.Counterপাইথনের ব্যাগ।
flornquake

1
দু'বার কিছু যুক্ত হলে কী হবে? অবস্থানটি কী হওয়া উচিত?
ম্যাককে

2
@McKay - যদি এটা collections.OrderDict আচরণ অনুসরণ করার ছিল এটি এখনও প্রাথমিক উপরন্তু অবস্থান হবে
wojtow

উত্তর:


206

এর জন্য একটি অর্ডারযুক্ত সেট (সম্ভাব্য নতুন লিঙ্ক ) রেসিপি রয়েছে যা পাইথন 2 ডকুমেন্টেশন থেকে উল্লেখ করা হয়েছে । এটি Py2.6 বা তার পরে এবং 3.0 বা তার পরে কোনও পরিবর্তন ছাড়াই চলে। ইন্টারফেসটি একটি সাধারণ সেট হিসাবে প্রায় হুবহু, ব্যতীত আরম্ভের জন্য একটি তালিকা দিয়ে করা উচিত।

OrderedSet([1, 2, 3])

এটি একটি মিউটেবলসেট, সুতরাং এর জন্য স্বাক্ষরটি .unionসেটের সাথে মেলে না, তবে এটিতে __or__অনুরূপ কিছু অন্তর্ভুক্ত থাকায় সহজেই যুক্ত করা যেতে পারে:

@staticmethod
def union(*sets):
    union = OrderedSet()
    union.union(*sets)
    return union

def union(self, *sets):
    for set in sets:
        self |= set

6
আমি আমার নিজের উত্তরটি নির্বাচন করেছি কারণ ডকুমেন্টেশন থেকে রেফারেন্সটি এটি একটি সরকারী উত্তরের নিকটবর্তী করে
কেসব্যাশ

49
ইন্টারফেস ঠিক স্বাভাবিক সেট বস্তুর হিসাবে একই নয়, অনেক অপরিহার্য পদ্ধতি যেমন অনুপস্থিত update, union, intersection
x অ্যাপল

5
অবগতির জন্য, আমি লক্ষ্য করেছি যে একটি সামান্য পরিমার্জিত সংস্করণ এর রেসিপি এই উত্তরে উদাহৃত হয়েছে PyPi যোগ করা হিসাবে "আদেশ-সেট"
জিওফ্রে Hing

7
আমি নিশ্চিত যে আপনাকে unionএকই ক্লাসে ডাকা দুটি পদ্ধতি থাকতে দেওয়া হচ্ছে না pretty শেষটি "জিতবে" এবং প্রথমটি রানটাইমের সময় উপস্থিত হতে ব্যর্থ হবে। এটি কারণ OrderedSet.union(কোনও প্যারেন্স নেই) একটি একক বস্তুর উল্লেখ করতে হয় ।
কেভিন

3
এছাড়াও "অর্ডারসেট" প্যাকেজ রয়েছে যা একই রেসিপিটির উপর ভিত্তি করে তবে সাইথনে প্রয়োগ করা হয়েছে - পিপিআইপিথন.অর্গ / পিপিআই / অর্ডারসেট
এমবিদেপল

149

অর্ডার করা সেটটি কার্যত অর্ডারযুক্ত অভিধানের একটি বিশেষ কেস।

অভিধানের কীগুলি অনন্য। সুতরাং, যদি কোনও আদেশিত অভিধানে মানগুলি উপেক্ষা করে (যেমন তাদের Noneনির্ধারিত করে ), তবে একটিতে মূলত একটি আদেশকৃত সেট থাকে set

পাইথন 3.1 এর হিসাবে আছে collections.OrderedDict। নীচে একটি অর্ডারডেটের একটি বাস্তবায়ন উদাহরণ। (দ্রষ্টব্য যে কয়েকটি কয়েকটি পদ্ধতির সংজ্ঞা দেওয়া বা ওভাররাইড করা দরকার: 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 = __sub__ 
    difference_update = __isub__
    intersection = __and__
    intersection_update = __iand__
    issubset = __le__
    issuperset = __ge__
    symmetric_difference = __xor__
    symmetric_difference_update = __ixor__
    union = __or__

1
@Casebash: হ্যাঁ, এক একটি বর্গ সংজ্ঞায়িত করতে পারেন OrderedSetযা উপশ্রেণী OrderedDictএবং abc.Setএবং তারপর সংজ্ঞায়িত __len__, __iter__এবং __contains__
স্টেফান202

1
@ স্টিফেন202: আফসোস, সংগ্রহের এবিসিগুলি বাস করে collectionsতবে অন্যথায় একটি ভাল পরামর্শ
u0b34a0f6ae

4
এটি সত্য, তবে ফলস্বরূপ আপনার প্রচুর অপচয় করার জায়গা রয়েছে যা suboptimal কর্মক্ষমতা বাড়ে।
ড্যানিয়েল কেটস

3
সংযোজন; সংগ্রহ.অর্ডারডিক্ট পাইথন ২.7 এও উপলব্ধ।
নুরবल्डফ

2
করণ OrderedSet([1,2,3])একটি টাইপরর উত্থাপন করে। কিভাবে কনস্ট্রাক্টর কাজ করে? অনুপস্থিত ব্যবহারের উদাহরণ।
x অ্যাপল

89

উত্তরটি হ'ল না, তবে আপনি collections.OrderedDictপাইথন স্ট্যান্ডার্ড লাইব্রেরি থেকে Noneএকই উদ্দেশ্যে (কী হিসাবে মানগুলি ) ব্যবহার করতে পারেন।

আপডেট : পাইথন 3.7 (এবং CPython 3.6) এর হিসাবে, মান dictহয় অর্ডার সংরক্ষণ নিশ্চিত এবং তুলনায় আরো performant হয় OrderedDict। (পশ্চাদপদ সামঞ্জস্যতা এবং বিশেষত পাঠযোগ্যতার জন্য, তবে আপনি ব্যবহার চালিয়ে যেতে ইচ্ছুক হতে পারেন OrderedDict))

dictঅর্ডার সংরক্ষণের সময় সদৃশ আইটেমগুলি নকল আইটেমগুলিকে ফিল্টার করার জন্য একটি আদেশকৃত সেট হিসাবে কীভাবে ব্যবহার করতে হয় তার উদাহরণ এখানে দেওয়া হয়েছে , যাতে একটি আদেশযুক্ত সেট অনুকরণ করা যায়। একটি ডিক তৈরির জন্য dictশ্রেণি পদ্ধতিটি ব্যবহার করুন fromkeys(), তারপরে কেবল keys()পিছনের জন্য জিজ্ঞাসা করুন ।

>>> keywords = ['foo', 'bar', 'bar', 'foo', 'baz', 'foo']

>>> list(dict.fromkeys(keywords))
['foo', 'bar', 'baz']

4
সম্ভবত উল্লেখযোগ্য যে এটি ভ্যানিলা দিয়েও (দ্রুত) কাজ করে dict.fromkeys()। তবে সেক্ষেত্রে মূল ক্রমটি কেবল সিপিথন 3.6+ বাস্তবায়নে সংরক্ষিত থাকে, সুতরাং OrderedDictআদেশের ক্ষেত্রে বিষয়টি আরও বহনযোগ্য সমাধান।
jez

1
মানগুলি স্ট্রিং না হলে কাজ করবে না
আনোয়ার হোসেন

4
@ আনোয়ার হোসেন keys = (1,2,3,1,2,1) list(OrderedDict.fromkeys(keys).keys())-> [1, 2, 3], অজগর -৩.৩ । এটা কাজ করে।
রারাটিড়ু

1
পাইথন 3.7+ এও সেট সেটটি অর্ডার সংরক্ষণ করতে পারি?
user474491

2
@ user474491 ভিন্ন dict, setপাইথন মধ্যে 3.7+ দুর্ভাগ্যবশত অর্ডার সংরক্ষণ করা হয় না।
সিজেড

39

আমি আপনাকে অর্ডারসেটের চেয়ে আরও ভাল কিছু করতে পারি: বল্টনগুলিতে একটি খাঁটি-পাইথন, 2 / 3- সামঞ্জস্যপূর্ণ IndexedSetটাইপ থাকে যা কেবল অর্ডার করা সেট নয়, তবে সূচিকরণকেও সমর্থন করে (তালিকার মতো) with

কেবল pip install boltons(বা setutils.pyআপনার কোডবেসে অনুলিপি করুন), IndexedSetএবং আমদানি করুন :

>>> from boltons.setutils import 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, তবে এর অর্থ হ'ল কোনও সমস্যা থাকলে আপনি আমাকে বাগ করতে পারেন । :)


39

পিপিআই-তে বাস্তবায়ন

যদিও অন্যরা উল্লেখ করেছেন যে পাইথনে (এখনও) কোনও সন্নিবেশ-অর্ডার সংরক্ষণের কোনও অন্তর্নির্মিত প্রয়োগ নেই, আমি অনুভব করছি যে এই প্রশ্নের একটি উত্তর অনুপস্থিত যা পাইপআই- তে কী পাওয়া যাবে তা জানিয়েছে ।

প্যাকেজ রয়েছে:

এগুলির কয়েকটি বাস্তবায়ন রেমন্ড হেট্টিংগার টু অ্যাক্টিভেটে পোস্ট করা রেসিপিটির উপর ভিত্তি করে যা এখানে অন্যান্য উত্তরেও উল্লেখ করা হয়েছে।

কিছু পার্থক্য

  • অর্ডার-সেট (সংস্করণ 1.1)
    • সুবিধা: ও (1) সূচী অনুসারে (যেমন my_set[5])
  • ওয়েট (সংস্করণ 0.1.3)
    • সুবিধা: ও (1) এর জন্য remove(item)
    • অসুবিধা: স্পষ্টত O (n) অনুসারে সূচকের অনুসারে s

উভয় বাস্তবায়নের ক্ষেত্রে ও () এর জন্য add(item)__contains__(item)( 1 item in my_set) রয়েছে।


2
একটি নতুন প্রতিযোগী হ'ল কালেকশন_সেটেডড.সেটলিস্টset.unionউত্তরাধিকার সূত্রে যদিও এর মতো কাজগুলি এতে কাজ করে না collections.abc.Set
টিমডিয়েলস

3
OrderedSetএখন সমর্থন করেremove
ওয়ারওয়ারিয়ুক

17

যদি আপনি সাজানো অর্ডার বজায় রাখতে অর্ডার করা সেটটি ব্যবহার করেন তবে পিপিআই থেকে সাজানো সেট প্রয়োগ ব্যবহার বিবেচনা করুন। Sortedcontainers মডিউল একটি উপলব্ধ SortedSet শুধু এই উদ্দেশ্যে নয়। কিছু সুবিধা: খাঁটি-পাইথন, দ্রুত-সি-সি বাস্তবায়ন, 100% ইউনিট পরীক্ষার কভারেজ, স্ট্রেস টেস্টিংয়ের ঘন্টা।

পাইপ দিয়ে পিপিআই থেকে ইনস্টল করা সহজ:

pip install sortedcontainers

মনে রাখবেন যে আপনি যদি না পারেন তবে pip installকেবল ওপেন সোর্স সংগ্রহস্থল থেকে sortlist.py এবং sortset.py ফাইলগুলি নীচে টানুন ।

একবার ইনস্টল হয়ে গেলে আপনি কেবল:

from sortedcontainers import SortedSet
help(SortedSet)

सॉোর্টকন্টেনার মডিউলটি বেশ কয়েকটি বিকল্প বাস্তবায়নের সাথে পারফরম্যান্সের তুলনাও বজায় রাখে ।

পাইথনের ব্যাগ ডেটা টাইপ সম্পর্কে জিজ্ঞাসা করা মন্তব্যের জন্য, বিকল্পভাবে একটি সোর্টলিস্ট ডেটা টাইপ রয়েছে যা ব্যাগকে দক্ষতার সাথে কার্যকর করতে ব্যবহার করা যেতে পারে।


নোট করুন যে সেখানকার SortedSetশ্রেণিতে সদস্যদের তুলনাযোগ্য এবং হ্যাশযোগ্য হতে হবে।
gsnedders

4
@gsnedders অন্তর্নির্মিত setএবং frozensetএছাড়াও উপাদানগুলি হ্যাশযোগ্য হতে হবে। তুলনামূলক সীমাবদ্ধতা এর জন্য সংযোজন SortedSet, তবে এটি একটি সুস্পষ্ট বাধাও।
gotgenes

2
নাম অনুসারে, এটি শৃঙ্খলা বজায় রাখে না। এটি সাজানো (সেট ([ক্রম])) ছাড়া আর কিছুই নয় যা আরও ভাল করে তোলে?
ldmtwo

@ldmtwo আমি নিশ্চিত নই যা আপনি উল্লেখ করছি কিন্তু পরিষ্কার হবে, SortedSet অংশ হিসেবে সাজানো পাত্রে সাজানো শৃঙ্খলা বজায় রাখার করে।
গ্রান্টজে

2
@ গ্রান্টজে - এটি সন্নিবেশ ক্রম বা সাজানোর ক্রম বজায় রাখে কিনা এর মধ্যে পার্থক্য । অন্যান্য উত্তরগুলির বেশিরভাগ সন্নিবেশ ক্রম সম্পর্কিত। আমি মনে করি আপনি আপনার প্রথম বাক্যটির ভিত্তিতে এটি সম্পর্কে ইতিমধ্যে অবগত আছেন তবে এলডিএমটিও সম্ভবত এটিই বলছে।
জাস্টিন

8

আপনি যদি ইতিমধ্যে আপনার কোডে পান্ডাস ব্যবহার করছেন তবে এর নিবন্ধটি এই নিবন্ধেIndex দেখানো মতো একটি অর্ডারযুক্ত সেটের মতো আচরণ করে ।

নিবন্ধ থেকে উদাহরণ:

indA = pd.Index([1, 3, 5, 7, 9])
indB = pd.Index([2, 3, 5, 7, 11])

indA & indB  # intersection
indA | indB  # union
indA - indB  # difference
indA ^ indB  # symmetric difference

আপনি এই উত্তরে একটি উদাহরণ অন্তর্ভুক্ত করতে পারেন? লিঙ্কগুলি কিছু সময়ের পরে ভেঙে যায়।
আলেচান

1
সেটগুলির মধ্যে পার্থক্যের জন্য, আপনাকে আসলে ব্যবহার করতে হবে indA.difference(indB), বিয়োগ চিহ্নটি মান বিয়োগফল সম্পাদন করে
gg349

7

একটু খেলা দেরী, কিন্তু আমি একটি বর্গ লিখেছি setlistঅংশ হিসেবে collections-extendedযে সম্পূর্ণরূপে কার্যকরী উভয় SequenceএবংSet

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

গিটহাব: https://github.com/mlenzen/col લેક્-- প্রসারিত

ডকুমেন্টেশন: http://collections-extended.lenzm.net/en/latest/

পিপিআই: https://pypi.python.org/pypi/col લેક્-- এক্সটেন্ডেড


7

কোন ব্যাপার OrderedSetকর্মকর্তা লাইব্রেরিতে। আমি আপনার রেফারেন্সের জন্য সমস্ত ডেটা স্ট্রাকচারের একটি বিস্তৃত চিটপত্র তৈরি করি।

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

3

ParallelRegression প্যাকেজের মাধ্যমে একটি উপলব্ধ setlist () সেট বর্গ আরো পদ্ধতি-সম্পূর্ণ অপশন ActiveState রেসিপি উপর ভিত্তি করে চেয়ে যে আদেশ দেন। এটি তালিকার জন্য উপলব্ধ সমস্ত পদ্ধতির সমর্থন করে এবং বেশিরভাগ যদি সেটগুলির জন্য সমস্ত পদ্ধতি উপলব্ধ না হয়।


2

অন্যান্য উত্তর হিসাবে উল্লেখ আছে, পাইথন 3.7+ হিসাবে, ডিক সংজ্ঞা দ্বারা আদেশ করা হয়। সাবক্লাসিংয়ের পরিবর্তে OrderedDictআমরা সাবক্লাসিং abc.collections.MutableSetবা typing.MutableSetডিকের কীগুলি ব্যবহার করে আমাদের মান সংরক্ষণ করতে পারি।

class OrderedSet(typing.MutableSet[T]):
    """A set that preserves insertion order by internally using a dict."""

    def __init__(self, iterable: t.Iterator[T]):
        self._d = dict.fromkeys(iterable)

    def add(self, x: T) -> None:
        self._d[x] = None

    def discard(self, x: T) -> None:
        self._d.pop(x)

    def __contains__(self, x: object) -> bool:
        return self._d.__contains__(x)

    def __len__(self) -> int:
        return self._d.__len__()

    def __iter__(self) -> t.Iterator[T]:
        return self._d.__iter__()

তারপরে:

x = OrderedSet([1, 2, -1, "bar"])
x.add(0)
assert list(x) == [1, 2, -1, "bar", 0]

আমি এই কোডটি একটি ছোট লাইব্রেরিতে রেখেছি , যাতে যে কেউ এটি ঠিক করতে pip installপারে।


-4

বিভিন্ন উদ্দেশ্যে কেবল বাছাই করা কল করা যথেষ্ট হবে। উদাহরণ স্বরূপ

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

আপনি যদি বারবার এটি ব্যবহার করতে যাচ্ছেন তবে বাছাই করা ফাংশনটি কল করে ওভারহেড হবে যাতে আপনি সেটটি পরিবর্তন করার পরে ফলাফলের তালিকাটি সংরক্ষণ করতে পারেন। আপনার যদি অনন্য উপাদান বজায় রাখতে এবং সাজানোর প্রয়োজন হয় তবে আমি অর্ডারডিক্টিক সংগ্রহ থেকে কোনওটিই নয় মান হিসাবে ব্যবহার করার পরামর্শের সাথে সম্মত।


43
অর্ডারডসেটের উদ্দেশ্য হ'ল তারা সেটে সেগুলিতে যে ক্রম যুক্ত হয়েছিল তা ক্রমে আইটেমগুলি পেতে সক্ষম হবেন। উদাহরণস্বরূপ আপনি সম্ভবত सॉোর্টসেট নামে পরিচিত হতে পারেন ...
সাময়িক রক্ষণাবেক্ষণ

-4

সুতরাং আমার কাছে একটি ছোট তালিকাও ছিল যেখানে আমার স্পষ্টতই অ-অনন্য মূল্যবোধ প্রবর্তনের সম্ভাবনা ছিল।

আমি কোনও ধরণের অনন্য তালিকার অস্তিত্ব অনুসন্ধান করেছি, কিন্তু তখন বুঝতে পেরেছি যে উপাদানটি যুক্ত করার আগে এটির অস্তিত্বের পরীক্ষা করা ঠিক কাজ করে।

if(not new_element in my_list):
    my_list.append(new_element)

আমি জানিনা যে এই সাধারণ পদ্ধতির বিষয়ে সতর্কতা আছে কি না তবে এটি আমার সমস্যার সমাধান করে।


এই পদ্ধতির মূল সমস্যাটি হ'ল ও (এন) এ রান যোগ করা। মানে বড় তালিকা সহ এটি ধীর হয়ে যায় er পাইথনের অন্তর্নির্মিত সেটগুলি যোগ করার উপাদানগুলিকে দ্রুত তৈরি করতে খুব ভাল। তবে সাধারণ ব্যবহারের ক্ষেত্রে এটি অবশ্যই কাজ করে!
ড্র্যাকোনিস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.