python - ما هي بنية البيانات الأساسية لقوائم بايثون؟



list data-structures (5)

ما هي بنية البيانات الأساسية المعتادة المستخدمة لتنفيذ نوع بيانات قائمة بايثون المدمجة؟


Answers

سي بايثون:

typedef struct {
    PyObject_VAR_HEAD
    /* Vector of pointers to list elements.  list[0] is ob_item[0], etc. */
    PyObject **ob_item;

    /* ob_item contains space for 'allocated' elements.  The number
     * currently in use is ob_size.
     * Invariants:
     *     0 <= ob_size <= allocated
     *     len(list) == ob_size
     *     ob_item == NULL implies ob_size == allocated == 0
     * list.sort() temporarily sets allocated to -1 to detect mutations.
     *
     * Items must normally not be NULL, except during construction when
     * the list is not yet visible outside the function that builds it.
     */
    Py_ssize_t allocated;
} PyListObject;

كما يمكن رؤيته في السطر التالي ، يتم الإعلان عن القائمة كصفيف من المؤشرات إلى PyObjects .

PyObject **ob_item;


مع وجود قائمة مرتبطة ، لا تكون العناصر بجانب بعضها البعض ، لذلك لا يمكنك على الفور حساب موضع العنصر الأوسط في الذاكرة:

يجب عليك التكرار على جميع العناصر للحصول على العنوان للعنصر الثاني ، ثم الانتقال إلى العنصر الثاني للحصول على عنوان العنصر الثالث ، وهكذا حتى تصل إلى العنصر الخامس.


يتم تنفيذ عناصر القائمة كمصفوفات. يتم تحسينها للعمليات ذات الطول الثابت السريع وتحمل تكاليف حركة الذاكرة O (n) للبوب (0) وإدراج العمليات (0، v) التي تغير كل من حجم وموضع تمثيل البيانات الأساسية.

راجع أيضًا: http://docs.python.org/library/collections.html#collections.deque

راجع للشغل ، أجد من المثير للاهتمام أن البرنامج التعليمي بايثون على هياكل البيانات توصي باستخدام البوب ​​(0) لمحاكاة طابور ولكن لا يذكر O (n) أو خيار deque.

http://docs.python.org/tutorial/datastructures.html#using-lists-as-queues


جواب باتريك (مقبول) هو الصحيح: if not a: هو الطريق الصحيح للقيام بذلك. رد هارلي هولكومب هو الصحيح أن هذا هو في دليل نمط PEP 8. ولكن ما لا تشرحه الأجوبة هو السبب في أنه من الجيد اتباع المصطلح - حتى لو كنت شخصياً تجد أنه غير واضح بما فيه الكفاية أو مربكًا لمستخدمي Ruby أو أيًا كان.

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

صحيح أنه if not a: لا يميز القوائم الفارغة من بلا ، أو رقمية 0 ، أو المجموعات الفارغة ، أو أنواع مجمعة فارغة أنشأها المستخدم ، أو أنواع فارغة لم يتم جمعها من قبل المستخدم ، أو صفيف NumPy أحادي العنصر يتصرفون كقياسيين ذوي قيم زائفة ، إلخ. وأحيانًا يكون من المهم أن تكون صريحًا بشأن ذلك. وفي هذه الحالة ، أنت تعرف ما تريد أن تكون صريحًا بشأنه ، لذا يمكنك اختبار ذلك بالضبط. على سبيل المثال ، if not a and a is not None: كلمة "أ" ولا "لا شيء" if not a and a is not None: تعني "أي شيء زائف باستثناء بلا" ، أما if len(a) != 0: تعني "التسلسلات الفارغة فقط - وأي شيء غير التسلسل هو خطأ هنا" وهكذا . بالإضافة إلى اختبار ما تريد اختباره بالضبط ، يشير هذا أيضًا إلى أن هذا الاختبار مهم.

ولكن عندما لا يكون لديك أي شيء يكون واضحًا بشأنه ، فإن أي شيء بخلاف if not a: هو تضليل القارئ. أنت تشير إلى شيء مهم عندما لا يكون كذلك. (يمكنك أيضًا جعل الشفرة أقل مرونة ، أو أبطأ ، أو أيا كان ، ولكن هذا أقل أهمية). وإذا كنت تضلل بشكل معتاد القارئ على هذا النحو ، فعندما تكون بحاجة إلى التمييز ، سوف تمر دون أن يلاحظها أحد كنت "تبكي الذئب" في جميع أنحاء التعليمات البرمجية الخاصة بك.





python list data-structures