एक अच्छा अजगर ट्री डेटा संरचना की तलाश [बंद]


92

मैं एक अच्छे ट्री डेटा स्ट्रक्चर क्लास की तलाश में हूं। मैं इस पैकेज में आया हूं , लेकिन चूंकि मैं पायथन (प्रोग्रामिंग नहीं) के लिए अपेक्षाकृत नया हूं, मुझे नहीं पता कि वहां कोई बेहतर व्यक्ति हैं या नहीं।

मैं यहाँ पर पाइथोनिस्टस से सुनना चाहता हूँ - क्या आपके पास एक पसंदीदा ट्री स्क्रिप्ट है जिसे आप नियमित रूप से उपयोग करेंगे और सुझाएंगे?

[संपादित करें]

'ट्री' द्वारा स्पष्ट करने के लिए, मेरा मतलब है कि एक साधारण अनियंत्रित पेड़ (हम्म, एक पुनरावर्ती परिभाषा का एक सा है - लेकिन उम्मीद है, कि चीजों को कुछ स्पष्ट करता है)। इस बारे में कि मुझे पेड़ की क्या आवश्यकता है (यानी केस का उपयोग करें)। मैं एक फ्लैट फ़ाइल से ट्री डेटा पढ़ रहा हूं और मुझे डेटा से एक पेड़ बनाने और पेड़ में सभी नोड्स को पार करने की आवश्यकता है।


कम से कम ट्रिपल डुप्लिकेट ... stackoverflow.com/questions/2482602/… साथ ही stackoverflow.com/questions/2358045/…
— eric

1
इस समय के दौरान, एक सरल, हल्का और एक्स्टेंसिबल ट्री डेटा संरचना है: anytree.readthedocs.io/en/latest
— c0fec0de

जवाबों:


38

अपना रोल करें। उदाहरण के लिए, अपने पेड़ को सूची की सूची के रूप में मॉडल करें। लोगों को बेहतर सिफारिश प्रदान करने से पहले आपको अपनी विशिष्ट आवश्यकता का विवरण देना चाहिए।

HelloGoodbye के सवाल के जवाब में, यह एक पेड़ को पुनरावृत्त करने के लिए एक नमूना कोड है।

def walk(node):
    """ iterate tree in pre-order depth-first search order """
    yield node
    for child in node.children:
        for n in walk(child):
            yield n

एक पकड़ यह पुनरावर्ती कार्यान्वयन हे (एन लॉग एन) है। यह उन सभी पेड़ों के लिए ठीक काम करता है जिनसे मुझे निपटना है। शायद पायथन 3 में उपसमूह मदद करेगा।


आप इस तरह के एक पेड़ में सभी तत्वों पर 'पायथोनिक' तरीके से कैसे लूप करते हैं?
— हैलोगूडीबाई

आमतौर पर आप DFS या BFS का उपयोग करके एक पेड़ को पुन: व्यवस्थित करते हैं। मैं आमतौर पर डीएफएस जैसे डीईएफ वॉक (पेड़) का उपयोग करके एक जनरेटर को लागू करता हूं: ...
— वाई वाई तुंग

1
डीएफएस और बीएफएस क्या है? ये शब्द मेरे लिए नए हैं।
— हैलोगुडेबी

1
DFS के लिए एक नमूना कोड जोड़ा गया।
— वाई वाई तुंग

1
गहराई-पहली खोज का अर्थ है कि एक नोड के बच्चों को उसके भाई-बहनों से पहले जाना जाता है। इसलिए यदि आपके पास `ए, ए, बी, [सी, डी]], [ई, [एफ, जी]]]` `है, तो, मान लें कि आप ई से पहले बी आते हैं, तो आप ई। चौड़ाई से पहले सी और डी भी देखें- पहली खोज का मतलब है कि एक ही स्तर पर सभी नोड्स उनके किसी भी बच्चे से पहले देखे जाते हैं, इसलिए B और E दोनों C, D, F, या G में से किसी से पहले जाएंगे
— मार्क रीड रीड

76

आप इस तरह से dicts के एक अच्छे पेड़ का निर्माण कर सकते हैं:

import collections

def Tree():
    return collections.defaultdict(Tree)

यह बिल्कुल वैसा नहीं हो सकता जैसा आप चाहते हैं लेकिन यह काफी उपयोगी है! मान केवल पत्ती नोड्स में सहेजे जाते हैं। यह कैसे काम करता है इसका एक उदाहरण है:

>>> t = Tree()
>>> t
defaultdict(<function tree at 0x2142f50>, {})
>>> t[1] = "value"
>>> t[2][2] = "another value"
>>> t
defaultdict(<function tree at 0x2142f50>, {1: 'value', 2: defaultdict(<function tree at 0x2142f50>, {2: 'another value'})}) 

अधिक जानकारी के लिए जिस्ट पर एक नज़र डालें ।


1
वाह, डिफॉल्ट का उपयोग करना एक शानदार विचार है!
— laike9m

महान और मैं हमेशा कोशिश करते हैं कि बसने वालों को छोड़कर दीवार का उपयोग करें।
— जिम्मी केन

5
एक नकारात्मक पक्ष यह है कि पेड़ के जोड़-तोड़ से संबंधित तरीकों को जोड़ना बहुत मुश्किल है। यह भी विकी में है और इसे
— स्वतःकरण

41

मुझे ब्रेट एलिस्टेयर क्रॉम्पम्प द्वारा लिखा गया एक मॉड्यूल मिला जो पूरा नहीं हुआ था। मैंने इसे समाप्त किया और इसे गीथूब पर सार्वजनिक किया और इसका नाम बदलकर treelib(मूल pyTree) रखा:

https://github.com/caesar0301/treelib

यह आपकी मदद कर सकता है ....


5
लाइसेंस GPL है, क्या अफ़सोस है
— denfromufa

12
यह लाइसेंस तब दिया गया था जब मैं इस बात से अनजान था कि लाइसेंस का क्या मतलब है। मैं इसका सरल लेकिन उपयोगी मॉड्यूल जानता हूं। संस्करण 1.3.0 के बाद से, मैं इसे अपाचे लाइसेंस के तहत पुनर्वितरित करता हूं। अब आप इसका उपयोग कर सकते हैं जहां आपको मूल कॉपीराइट की घोषणा के साथ इसकी आवश्यकता होती है।
— caesar0301

9

डिफ़ॉल्ट लाइन का उपयोग करके सिंगल लाइन ट्री के साथ ऊपर दिए गए उत्तर पर निर्माण करना , आप इसे एक वर्ग बना सकते हैं। यह आपको एक कंस्ट्रक्टर में चूक को स्थापित करने और अन्य तरीकों से उस पर निर्माण करने की अनुमति देगा।

class Tree(defaultdict):
    def __call__(self):
        return Tree(self)

    def __init__(self, parent):
        self.parent = parent
        self.default_factory = self

यह उदाहरण आपको एक बैक रेफरेंस बनाने की अनुमति देता है ताकि प्रत्येक नोड पेड़ में अपने माता-पिता को संदर्भित कर सके।

>>> t = Tree(None)
>>> t[0][1][2] = 3
>>> t
defaultdict(defaultdict(..., {...}), {0: defaultdict(defaultdict(..., {...}), {1: defaultdict(defaultdict(..., {...}), {2: 3})})})
>>> t[0][1].parent
defaultdict(defaultdict(..., {...}), {1: defaultdict(defaultdict(..., {...}), {2: 3})})
>>> t2 = t[0][1]
>>> t2
defaultdict(defaultdict(..., {...}), {2: 3})
>>> t2[2]
3

इसके बाद, आप क्लास ट्री पर __setattr__ को भी ओवरराइड कर सकते हैं, ताकि जब माता-पिता को आश्वस्त किया जाए, तो यह उस माता-पिता से एक बच्चे के रूप में इसे हटा देता है। इस पैटर्न के साथ बहुत सारी सामग्री।


उपरोक्त उदाहरण में t [0] [1] [2] के लिए माता-पिता टूट गए हैं। गुण: 'int' ऑब्जेक्ट में कोई विशेषता 'पैरेंट' नहीं है
— MatthieuBizien

@oao यह टूटा नहीं है। आप t [0] [1] [2] = 3 निर्दिष्ट कर रहे हैं। इसलिए t [0] [1] [2] एक डिफ़ॉल्ट प्रकार नहीं होने जा रहा है, लेकिन एक नंबर प्रकार (डिफ़ॉल्ट रूप में डिफॉल्ट के लिए उपयोग किया जाता है) लापता तत्व)। यदि आप चाहते हैं कि यह एक डिफ़ॉल्ट हो, तो आपको असाइनमेंट के बिना t [0] [1] [2] का उपयोग करने की आवश्यकता है।
— सैंडी चैपमैन

7

आदेश दिए गए बच्चों के साथ एक पेड़ के लिए, मैं आमतौर पर इस तरह का कुछ करूँगा (हालांकि थोड़ा कम सामान्य, जो मैं कर रहा हूं उसके अनुरूप):

class TreeNode(list):

    def __init__(self, iterable=(), **attributes):
        self.attr = attributes
        list.__init__(self, iterable)

    def __repr__(self):
        return '%s(%s, %r)' % (type(self).__name__, list.__repr__(self),
            self.attr)

आप एक dictया उपयोग करने के साथ तुलनीय कुछ कर सकते हैं DictMixinया यह अधिक आधुनिक वंशज हैं यदि आप चाहते हैं कि बिना मोड के बच्चों को कुंजी द्वारा एक्सेस किया जाए।



5

पायथन में पेड़ों के कार्यान्वयन के लिए एक और अच्छा और आसान तरीका है pyTree: https://github.com/caesar0301/pyree

पेड़ से पेड़ को देखने की क्षमता भी मिलती है:

Harry[harry]
|___ Jane[jane]
|    |___ Diane[diane]
|         |___ George[george]
|              |___ Jill[jill]
|         |___ Mary[mary]
|    |___ Mark[mark]
|___ Bill[bill]

2
पेड़ को देखने की कोशिश करने के लिए एक प्लस, भले ही प्रतिपादन भयानक था।
— हैलोगूडीबाई


4

यहाँ कुछ मैं काम कर रहा था।

class Tree:
    def __init__(self, value, *children):
        '''Singly linked tree, children do not know who their parent is.
        '''
        self.value = value
        self.children = tuple(children)

    @property
    def arguments(self):
        return (self.value,) + self.children

    def __eq__(self, tree):
        return self.arguments == tree.arguments

    def __repr__(self):
        argumentStr = ', '.join(map(repr, self.arguments))
        return '%s(%s)' % (self.__class__.__name__, argumentStr)

इस तरह से उपयोग करें (उदाहरण मान के रूप में प्रयुक्त संख्या): t = Tree(1, Tree(2, Tree(4)), Tree(3, Tree(5)))


3

क्या बीट्रीज़ मदद करेंगे ? वे ज़ोप ऑब्जेक्ट डेटाबेस कोड का हिस्सा हैं। पूरे ZODB पैकेज को डाउनलोड करना थोड़ा अधिक है, लेकिन मुझे उम्मीद है कि BTrees मॉड्यूल कम से कम कुछ अलग होगा।


2

मुझे लगता है, अधिक उन्नत डेटा संरचनाओं के साथ समस्याओं पर अपने स्वयं के अनुभव से, कि आप यहां सबसे महत्वपूर्ण बात कर सकते हैं, डेटा संरचनाओं के रूप में तनाव की सामान्य अवधारणा पर एक अच्छा ज्ञान प्राप्त करना है। यदि आप अवधारणा के पीछे मूल तंत्र को समझते हैं तो आपकी समस्या को हल करने वाले समाधान को लागू करना काफी आसान होगा। अवधारणा का वर्णन करने वाले कई अच्छे स्रोत हैं। इस विशेष समस्या पर सालों पहले मुझे "बचाया", "द आर्ट ऑफ़ कंप्यूटर प्रोग्रामिंग" में धारा 2.3 था।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.