python - حلقة - كتابة برنامج بلغة بايثون




كيف يمكنني فرز قائمة القواميس حسب قيم القاموس في بايثون؟ (12)

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

هذه

[{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}]

فرز حسب الاسم ، يجب أن تصبح

[{'name':'Bart', 'age':10}, {'name':'Homer', 'age':39}]

أعتقد أنك قصدت:

[{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}]

سيتم فرز هذا على النحو التالي:

sorted(l,cmp=lambda x,y: cmp(x['name'],y['name']))

إذا كنت تريد فرز القائمة بواسطة مفاتيح متعددة ، فيمكنك القيام بما يلي:

my_list = [{'name':'Homer', 'age':39}, {'name':'Milhouse', 'age':10}, {'name':'Bart', 'age':10} ]
sortedlist = sorted(my_list , key=lambda elem: "%02d %s" % (elem['age'], elem['name']))

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


باستخدام التحويل شوارتسيان من بيرل ،

py = [{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}]

فعل

sort_on = "name"
decorated = [(dict_[sort_on], dict_) for dict_ in py]
decorated.sort()
result = [dict_ for (key, dict_) in decorated]

يعطي

>>> result
[{'age': 10, 'name': 'Bart'}, {'age': 39, 'name': 'Homer'}]

المزيد عن تحويل بيرل شوارتسيان

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


جربت شيئًا كهذا:

my_list.sort(key=lambda x: x['name'])

عملت للأعداد الصحيحة كذلك.


في وقت ما نحن بحاجة إلى استخدام lower() على سبيل المثال

lists = [{'name':'Homer', 'age':39},
  {'name':'Bart', 'age':10},
  {'name':'abby', 'age':9}]

lists = sorted(lists, key=lambda k: k['name'])
print(lists)
# [{'name':'Bart', 'age':10}, {'name':'Homer', 'age':39}, {'name':'abby', 'age':9}]

lists = sorted(lists, key=lambda k: k['name'].lower())
print(lists)
# [ {'name':'abby', 'age':9}, {'name':'Bart', 'age':10}, {'name':'Homer', 'age':39}]

قد يبدو الأمر أكثر نظافة باستخدام مفتاح بدلاً من cmp:

newlist = sorted(list_to_be_sorted, key=lambda k: k['name']) 

أو كما اقترح JFSebastian وآخرون ،

from operator import itemgetter
newlist = sorted(list_to_be_sorted, key=itemgetter('name')) 

للتأكد من اكتمالها (كما هو موضح في التعليقات من قبل fitzgeraldsteele) ، أضف reverse=True للترتيب التنازلي

newlist = sorted(l, key=itemgetter('name'), reverse=True)

هنا هو الحل العام البديل - يقوم بفرز عناصر من مفاتيح بواسطة مفاتيح والقيم. ميزة ذلك - لا حاجة لتحديد المفاتيح ، وستظل تعمل إذا كانت بعض المفاتيح مفقودة في بعض القواميس.

def sort_key_func(item):
    """ helper function used to sort list of dicts

    :param item: dict
    :return: sorted list of tuples (k, v)
    """
    pairs = []
    for k, v in item.items():
        pairs.append((k, v))
    return sorted(pairs)
sorted(A, key=sort_key_func)


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

يمكنك فعلها بهذه الطريقة:

def mykey(adict): return adict['name']
x = [{'name': 'Homer', 'age': 39}, {'name': 'Bart', 'age':10}]
sorted(x, key=mykey)

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

from operator import itemgetter
x = [{'name': 'Homer', 'age': 39}, {'name': 'Bart', 'age':10}]
sorted(x, key=itemgetter('name'))

a = [{'name':'Homer', 'age':39}, ...]

# This changes the list a
a.sort(key=lambda k : k['name'])

# This returns a new list (a is not modified)
sorted(a, key=lambda k : k['name']) 

import operator
a_list_of_dicts.sort(key=operator.itemgetter('name'))

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


my_list = [{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}]

my_list.sort(lambda x,y : cmp(x['name'], y['name']))

سوف my_list الآن ما تريده.

(بعد 3 سنوات) تم تعديلها لإضافة:

الحجة key الجديدة هي أكثر كفاءة ومتانة. تبدو الإجابة الأفضل الآن كما يلي:

my_list = sorted(my_list, key=lambda k: k['name'])

... إن lambda ، IMO ، أسهل في الفهم من operator.itemgetter ، لكن YMMV.





data-structures