تعلم البرمجة مع Python


الدرس: تطبيق طريقتين للفرز في Python


الصفحة السابقة
يمكن أن يكون فرز أي قائمة معلومات مفيدًا جدًا ... وغالبًا ما يكون صعبًا. تعطينا Python العديد من التقنيات للفرز ، سواء كانت قوائم بسيطة من الأرقام أو السلاسل أو البيانات الأكثر تعقيدًا (مثل الكائنات التي أنشأنا فئاتنا الخاصة).

هذا الفصل عبارة عن قوس: يمكنك الانتقال مباشرة إلى الفصل التالي دون مشكلة ، والعودة إلى هذا الفصل لاحقًا.

أول طريقة للفرز



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

الفرز هو ترتيب القائمة بطريقة متماسكة. على سبيل المثال ، قد ترغب في فرز قائمة الأسماء أبجديًا. أو قد ترغب في فرز قائمة الأرقام من الأصغر إلى الأكبر.

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

طريقتان


لفرز سلسلة من البيانات ، تقدم لنا Python طريقتين:

  1. الأول هو طريقة القائمة. ويطلق عليها ببساطة sort (فرز بالإنجليزية) . إنها تعمل في القائمة بنفسها وبالتالي تغير ترتيبها ، إذا لزم الأمر.
  2. الثانية هي وظيفة sorted . إنها وظيفة مضمنة ، أي أنها متوفرة تلقائيًا في Python دون الحاجة إلى استيراد أي شيء. وخلافا للطريقةsort من الفئة list  ، sorted تعمل على أي نوع من التسلسل (الصفوف (tuple)، قائمة أو حتى القاموس) . هناك اختلاف مهم عن طريقة list.sort  وهو أنه لا يعدل الكائن الأصلي ، ولكنه يعيد كائنًا جديدًا.
دعنا نرى بعض الأمثلة:

>>> prenoms = ["Jacques", "Laure", "André", "Victoire", "Albert", "Sophie"]
>>> prenoms.sort()
>>> prenoms
['Albert', 'André', 'Jacques', 'Laure', 'Sophie', 'Victoire']
>>> # Et avec la fonction 'sorted'
... prenoms = ["Jacques", "Laure", "André", "Victoire", "Albert", "Sophie"]
>>> sorted(prenoms)
['Albert', 'André', 'Jacques', 'Laure', 'Sophie', 'Victoire']
>>> prenoms
['Jacques', 'Laure', 'André', 'Victoire', 'Albert', 'Sophie']
>>>
 
يجب أن تلاحظ شيئين هنا:
  1. 1. أولاً ، صنفت بايثون قائمتنا أبجديًا. سنرى لماذا في وقت لاحق.
  2. 2. الطريقة الثانية (باستخدام الوظيفة sorted )لم تقم بتعديل القائمة ، بل قامت فقط بإرجاع قائمة مرتبة جديدة.  طريقة القائمة sort ، فقد عملت على قائمتنا وعدّلتها.

نظرة عامة على معايير الفرز


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


>>> sorted([1, 8, -2, 15, 9])
[-2, 1, 8, 9, 15]
>>> sorted(["1", "8", "-2", "15", "9"])
['-2', '1', '15', '8', '9']
>>>
 
الجواب يكمن في الفرق بين السطر 1 والسطر 3. هل وجدته؟

بالنسبة لبايثون ، تعتمد طريقة الفرز على نوع العناصر التي يحتويها التسلسل. طُلب منه فرز قائمة الأرقام ( النوع int  ) و فرز Python من الأصغر إلى الأكبر. بدون مفاجأة.

ومع ذلك ، في السطر 3 ، يُطلب فرز نفس القائمة ، باستثناء أن أرقامنا أصبحت سلاسل (النوع str  ) . لذلك تختار Python فرز القائمة أبجديًا.

ماذا لو كانت لدينا قائمة تحتوي على عدة أنواع؟

في هذه الحالة ، ستخبرك Python ، بطريقتها الخاصة ، بأنها لا تعرف طريقة الفرز التي تختارها.


>>> sorted([1, "8", "-2", "15", 9])
Traceback (most recent call last):
  File "", line 1, in 
TypeError: unorderable types: str() < int()
>>>  
تحتوي قائمتنا على أرقام (نوع int  ) وسلاسل (type str ) . قد لا تكون رسالة الخطأ واضحة تمامًا حتى نعرف كيف تقوم بايثون بفرز التسلسل ، وسنرى ذلك لاحقًا في الفصل.

في غضون ذلك ، دعنا نلقي نظرة على أنواع أكثر تحديدًا!

الفرز بمفاتيح دقيقة



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

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


etudiants = [
    ("Clément", 14, 16),
    ("Charles", 12, 15),
    ("Oriane", 14, 18),
    ("Thomas", 11, 12),
    ("Damien", 12, 15),
]
 
تذكر: العمود الأول ، الاسم الأول ، العمود الثاني ، العمر والعمود الثالث ، المتوسط ​​بين 0 و 20.

الآن إذا حاولت فرز هذه القائمة دون تحديد طريقة:


>>> sorted(etudiants)
[
    ('Charles', 12, 15),
    ('Clément', 14, 16),
    ('Damien', 12, 15),
    ('Oriane', 14, 18),
    ('Thomas', 11, 12)
]
>>>
 
لا تظهر القائمة بهذا الشكل في المترجم الافتراضي ، لقد قمت للتو بتعديل النتيجة لجعلها أكثر قابلية للقراءة.

أهم شيء بالنسبة لنا هو أن الفرز يبدو أنه تم في العمود الأول: في الأسماء الأولى. الترتيب الذي تم إرجاعه هو ترتيب الطلاب حسب الترتيب الأبجدي.

الآن ، لنفترض أننا نريد الفرز حسب التصنيف.

فقط قم بتغيير أعمدة قائمتنا ، أليس كذلك؟

نعم ، إنه حل وربما يكون الحل الذي نفكر فيه هو الأسرع: تغيير أعمدة قائمتنا ، ووضع الملاحظات في بداية المجموعة ، ثم فرز القائمة.

لكن هناك أسهل!

الحجة الرئيسية


تحتوي كل من طريقة list.sort  أو الوظيفة sorted على معلمة اختيارية تسمى المفتاحkey)) .

هذه الحجة تتوقع ... وظيفة. انتظر! ساوضح.

تأخذ الوظيفة المراد تمريرها كمعامل عنصرًا من القائمة وتعيد ما يجب فرزه.

إذن ، أول شيء هو إنشاء دالة؟

نعم ، ولكن بطريقة بسيطة إلى حد ما: سنستخدم وظائف لامدا الخاصة بنا . انت تتذكر ؟ أعطيك عينة صغيرة من التعليمات البرمجية إذا لزم الأمر:


>>> doubler = lambda x: x * 2
>>> doubler
<function <lambda> at 0x00000000029AD1E0>
>>> doubler(8)
16
>>>
 
وظائف Lambdas  هي وظائف خاصة يمكن إنشاؤها باستخدام الكلمة الأساسية lambda .

تركيبها كما يلي:

  1. أولاً ، بعد الكلمة الأساسية lambda ، وسيطات الوظيفة المراد إنشاؤها ، مفصولة بفاصلة إذا كان هناك العديد منها ؛
  2. ثم القولون ( :) ؛
  3. ثم ما تعيده الوظيفة. هنا ، نعيد المعلمة 2.
لماذا هذا التذكير على لامدا؟

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

  • عنصر قائمة الطلاب لدينا عبارة عن مجموعة تحتوي على الاسم الأول للطالب وعمره ومتوسطه ؛
  • نريد فرز جدول الطلاب وفقًا للدرجات (العمود الثالث من المجموعة).
هل تساعدك هذه المعلومات في إنشاء وظيفة لامدا الخاصة بنا ؟

هاهو :


lambda colonnes: colonnes[2]
 
ستحتوي الأعمدة على عنصر من قائمة الطلاب (أي مجموعة). إذا اعدنا colonnes[2]، فهذا يعني أننا نريد استرداد متوسط ​​الطالب (العمود الثالث). تذكر ، بالنسبة إلى tuple ، يكون العمود الأول دائمًا 0  .

الآن دعنا نحاول فرز قائمة الطلاب لدينا حسب متوسطهم:


>>> sorted(etudiants, key=lambda colonnes: colonnes[2])
[
    ('Thomas', 11, 12), 
    ('Charles', 12, 15), 
    ('Damien', 12, 15), 
    ('Clément', 14, 16),
    ('Oriane', 14, 18)
]
>>>
 
إذا كان الكود لا يبدو واضحًا لك ، خذ الوقت الكافي لقراءة التفسيرات مرة أخرى. يستغرق الأمر بعض الوقت للتكيف مع وظائف lambdas ، لكنك ستجد أنها مفيدة جدًا في بعض الأحيان.

فرز قائمة كائنات


حتى الآن ، قمنا بفرز القوائم التي تحتوي على أرقام أو سلاسل. هذه كائنات بالطبع ، لكن الآن أود أن أوضح لك كيفية فرز الكائنات من الفئات التي أنشأناها.

سآخذ نفس المثال من جدول طلابنا. ببساطة ، بدلاً من الاحتفاظ بالمجموعات ، سنحتفظ بالعناصر. أكثر سهولة وقراءة ، أجدها:


class Etudiant:

    """ فئة تمثل طالبًا.

    نحن نمثل الطالب باسمه الأول (سمة الاسم الأول) ، عمره
    (سمة العمر) ومتوسط درجاتها (متوسط السمة ، بين 0 و 20).

    معلمات المنشئ:
        الاسم الأول - الاسم الأول للطالب
        العمر - عمر الطالب
        متوسط - متوسط الطالب

    """

    def __init__(self, prenom, age, moyenne):
        self.prenom = prenom
        self.age = age
        self.moyenne = moyenne

    def __repr__(self):
        return "<Étudiant {} (âge={}, moyenne={})>".format(
                self.prenom, self.age, self.moyenne)
 
الآن دعنا نعيد إنشاء قائمتنا:

etudiants = [
    Etudiant("Clément", 14, 16),
    Etudiant("Charles", 12, 15),
    Etudiant("Oriane", 14, 18),
    Etudiant("Thomas", 11, 12),
    Etudiant("Damien", 12, 15),
]
 
إذا حاولت فرز قائمتنا كما هي ، فسوف تحصل على خطأ يبدو مألوفًا لك:

>>> etudiants
[
    <Étudiant Clément (âge=14, moyenne=16)>,
    <Étudiant Charles (âge=12, moyenne=15)>,
    <Étudiant Oriane (âge=14, moyenne=18)>,
    <Étudiant Thomas (âge=11, moyenne=12)>,
    <Étudiant Damien (âge=12, moyenne=15)>
]
>>> sorted(etudiants)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: unorderable types: Etudiant() < Etudiant()
>>>
 
لا تعرف بايثون كيفية فرز طلابنا. هناك طريقتان لشرح ذلك له:

  1. الأول هو تحديد طريقة __lt__  الخاصة لفئتنا . إنها بالفعل هذه الطريقة (المستخدمة للمقارنة) التي تستخدمها بايثون لفرز القائمة ، من خلال مقارنة كل عنصر من عناصرها . و __lt__ (أقل من) يتوافق طريقة ل < المشغل .
  2. يمكننا أيضًا استخدام الوسيطة الرئيسية ، كما فعلنا سابقًا.
هنا احتمالنا الثاني أكثر صلة. تعد إعادة تعريف طريقة __lt__ فكرة جيدة إذا كان الكائن لدينا عبارة عن رقم (على سبيل المثال ، مدة أو ساعة). في هذه الحالة المحددة ، من الأفضل استخدام الوسيطة الرئيسية للوظيفة التي تم فرزها (أو طريقة list.sort  ) .

هل يمكنك فرز قائمة الطلاب هذه وفقًا لمتوسطهم؟

ها هو الكود:


>>> sorted(etudiants, key=lambda etudiant: etudiant.moyenne)
[
    <Étudiant Thomas (âge=11, moyenne=12)>,
    <Étudiant Charles (âge=12, moyenne=15)>,
    <Étudiant Damien (âge=12, moyenne=15)>,
    <Étudiant Clément (âge=14, moyenne=16)>,
    <Étudiant Oriane (âge=14, moyenne=18)>
]
>>>
 
نحصل على نفس الشيء كما في تمريننا السابق ، عندما استخدمنا المجموعات. أنا شخصيا أجد هذه الطريقة أكثر قابلية للقراءة.

فرز بترتيب عكسي


غالبًا ما نرغب في الفرز بترتيب عكسي. على سبيل المثال ، نريد فرز طلابنا بترتيب عكسي للعمر (من الأكبر إلى الأصغر).

أحد الحلول هو فرز القائمة ثم عكسها ، ولكن مرة أخرى هناك حل أسرع: الحجة العكسية .

إنها وسيطة منطقية يمكن تمريرها إلى طريقة القائمةsort أو إلى الوظيفة sorted .

على سبيل المثال ، دعنا نحاول تصنيف طلابنا بترتيب عكسي للعمر:


>>> sorted(etudiants, key=lambda etudiant: etudiant.age, reverse=True)
[
    <Étudiant Clément (âge=14, moyenne=16)>,
    <Étudiant Oriane (âge=14, moyenne=18)>,
    <Étudiant Charles (âge=12, moyenne=15)>,
    <Étudiant Damien (âge=12, moyenne=15)>,
    <Étudiant Thomas (âge=11, moyenne=12)>
]
>>>
 
بسيط جدا ، أليس كذلك؟ 


أسرع وأكثر كفاءة



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

لكنك قلت إن المعلمة الرئيسية تتوقع وظيفة ، ألا يمكننا تحديد وظيفة "عادية"؟

نعم نعم. إنه ممكن تمامًا. لكن في معظم الأوقات ، تؤدي إحدى وظائف وحدة المشغل التي سنراها المهمة بشكل جيد للغاية.

وظائف وحدة المشغل


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

رتب قائمة من المجموعات


أولاً ، دعنا نرى مثالنا مع tuples :


etudiants = [
    ("Clément", 14, 16),
    ("Charles", 12, 15),
    ("Oriane", 14, 18),
    ("Thomas", 11, 12),
    ("Damien", 12, 15),
]
 
إذا أردنا الفرز حسب المتوسط التصاعدي ، فقد رأينا أنه يكفي القيام بما يلي:

sorted(etudiants, key=lambda etudiant: etudiant[2])
 
للقيام بالشيء نفسه بدون وظيفة lambda ، باستخدام وظيفة itemgetter لوحدة المشغل :

from operator import itemgetter
sorted(etudiants, key=itemgetter(2))
 
نستدعي وظيفة  itemgetter مع المعلمة 2   . كائن operator.itemgetter  كائن يتم إنشاءه وتمريره إلى  المعلمة key للوظيفة sorted . بعد ذلك ، لكل طالب في قائمتنا ، يتم استدعاء كائن operator.itemgetter .  وهو يُرجع متوسط ​​تقدير الطالب.

في النهاية ، نحصل على نفس النتيجة كما في دالة lambda الخاصة بنا ، ولكن هذه الطريقة أسرع على كمية كبيرة من البيانات ، وبمجرد أن نتعود على مظهرها ، يسهل قراءتها.

فرز قائمة الكائنات


يمكننا أن نفعل الشيء نفسه إذا قمنا بالتكرار من خلال قائمة الكائنات ، ولكن هذه المرة استخدمنا وظيفة Attrgetter  . أعطيك الكود للتأكد من أن لديك نفس الشيء مثلي:


class Etudiant:

    """ فئة تمثل طالبًا.

     نحن نمثل الطالب باسمه الأول (سمة الاسم الأول) ، عمره
     (سمة العمر) ومتوسط درجاتها (متوسط السمة ، بين 0 و 20).

     معلمات الشركة المصنعة:
         الاسم الأول - الاسم الأول للطالب
         العمر - عمر الطالب
         متوسط - متوسط الطالب
    """

    def __init__(self, prenom, age, moyenne):
        self.prenom = prenom
        self.age = age
        self.moyenne = moyenne

    def __repr__(self):
        return "<Étudiant {} (âge={}, moyenne={})>".format(
                self.prenom, self.age, self.moyenne)

etudiants = [
    Etudiant("Clément", 14, 16),
    Etudiant("Charles", 12, 15),
    Etudiant("Oriane", 14, 18),
    Etudiant("Thomas", 11, 12),
    Etudiant("Damien", 12, 15),
]
 
والآن لفرز قائمة الطلاب لدينا عن طريق تصنيف متوسط تصاعدي:

from operator import attrgetter
sorted(etudiants, key=attrgetter("moyenne"))
 
النظام هو نفسه ، باستثناء أننا نعمل هنا على قائمة العناصر وأن الحساب يتم على سمة من سمات الكائن (هنا "متوسط"  ) بدلاً من tuple .

فرز حسب معايير متعددة


يعد الفرز وفقًا لمعيار واحد أمرًا رائعًا بالفعل ، ولكن الفرز وفقًا لعدة معايير يمكن أن يكون أفضل. إذا أردنا ، على سبيل المثال ، فرز طلابنا حسب العمر ومتوسط ​​الدرجة. أي أن الفرز سيتم حسب العمر ، ولكن إذا كان اثنان من الطلاب في نفس العمر ، فسيتم الفرز في المتوسط.

الاخبار الجيدة ؟ لا شيء جديد: فقط قم بتمرير معامل جديد إلى وظيفة Attrgetter  :


>>> sorted(etudiants, key=attrgetter("age", "moyenne"))
[
    <Étudiant Thomas (âge=11, moyenne=12)>,
    <Étudiant Charles (âge=12, moyenne=15)>,
    <Étudiant Damien (âge=12, moyenne=15)>,
    <Étudiant Clément (âge=14, moyenne=16)>,
    <Étudiant Oriane (âge=14, moyenne=18)>
]
>>>
 
ربما لاحظت أن ترتيب تشارلز ودامين في القائمة هو نفسه كما كان من قبل ، حتى لو قام الطلاب الآخرون بتغيير أماكنهم: في الواقع ، تشارلز ودامين هما نفس العمر ونفس المعدل وترتيبهما لم يتم تعديله بواسطة Python .

هذه الخاصية تسمى "الاستقرار" . إذا كان عنصران من عناصر التسلسل المراد مقارنتهما متطابقين ، فسيتم الحفاظ على ترتيبهما.

تسمح لنا خاصية الفرز في بايثون بربط أنواعنا.

فرز التسلسل


لتظهر لك مثالًا ملموسًا ، سنقوم بتغيير العناصر: سنعمل على جرد للمنتجات بسعرها وكميتها المباعة.


class LigneInventaire:

    """ فئة تمثل صفًا من جرد المبيعات.

     السمات المتوقعة من قبل الشركة المصنعة:
         المنتج - اسم المنتج
         price (السعر) - سعر الوحدة للمنتج
         الكمية - كمية المنتج المباع.
    """

    def __init__(self, produit, prix, quantite):
        self.produit = produit
        self.prix = prix
        self.quantite = quantite

    def __repr__(self):
        return "<Ligne d'inventaire {} ({}X{})>".format(
                self.produit, self.prix, self.quantite)

# Création de l'inventaire
inventaire = [
    LigneInventaire("pomme rouge", 1.2, 19),
    LigneInventaire("orange", 1.4, 24),
    LigneInventaire("banane", 0.9, 21),
    LigneInventaire("poire", 1.2, 24),
]
 
نريد فرز هذه القائمة حسب السعر والكمية. سهل ، هذا ما فعلناه أعلاه قليلاً:

from operator import attrgetter
sorted(inventaire, key=attrgetter("prix", "quantite"))
 
الذي يعيد:

 [
    <Ligne d'inventaire banane (0.9X21)>,
    <Ligne d'inventaire pomme rouge (1.2X19)>,
    <Ligne d'inventaire poire (1.2X24)>,
    <Ligne d'inventaire orange (1.4X24)>
]
 
ولكن ماذا لو أردت الفرز عن طريق زيادة السعر وخفض الكمية؟ وهذا يعني أننا نريد الفرز من خلال زيادة السعر ، ولكن إذا كان لخطي مخزون نفس السعر ، فسنقوم بالفرز بترتيب تنازلي للكمية؟

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

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

هذا هو كود لفرزنا. أولاً بالكمية ثم بالسعر:


inventaire.sort(key=attrgetter("quantite"), reverse=True)
sorted(inventaire, key=attrgetter("prix"))
 
ويجب أن تحصل على:

 [
    <Ligne d'inventaire banane (0.9X21)>,
    <Ligne d'inventaire poire (1.2X24)>,
    <Ligne d'inventaire pomme rouge (1.2X19)>,
    <Ligne d'inventaire orange (1.4X24)>
]
 
نستخدم هنا طريقة القائمة sort حيث كان بإمكاننا استخدام وظيفةsorted .

انظر بشكل خاص إلى الترتيب الذي يظهر به الكمثرى(poire ) والتفاح الأحمر(pomme rouge): يكون لخطي المخزون نفس السعر ، ولكن نظرًا لبيع الكمثرى بكميات أكبر ، فإنه يظهر أولاً. لم يكن هذا ممكناً لولا الاستقرار في الفرز.

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

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

باختصار


  • يتم الفرز في Python باستخدام طريقة القائمة sort ، والتي تعدل القائمة الأصلية ، والوظيفة sorted ، والتي لا تعدل القائمة (أو التسلسل) الذي تم تمريره كمعامل ؛
  • يمكنك تحديد الوظائف الرئيسية باستخدام الوسيطة key . يتم استدعاء هذه الوظائف لكل عنصر من عناصر التسلسل لفرز ، وإرجاع معيار الفرز ؛
  • والمشغل  operator  يوفر الوظائف itemgetter   و attrgetter   التي يمكن أن تكون مفيدة جدا وظائف أساسية، إذا كنت ترغب في فرز قائمة من المجموعات أو قائمة الكائنات التي كتبها صفة؛
  • يعتبر الترتيب في Python "مستقرًا" ، أي أن ترتيب عنصرين في القائمة لا يتغير إذا كانا متساويين. تسمح هذه الخاصية بالفرز المتسلسل.