উত্তর:
এটি কোনও সিএমপি পরিবর্তে কোনও কী ব্যবহার করে ক্লিনার দেখায়:
newlist = sorted(list_to_be_sorted, key=lambda k: k['name'])
বা জেএফেসেস্টিয়ান এবং অন্যরা যেমন পরামর্শ দিয়েছে,
from operator import itemgetter
newlist = sorted(list_to_be_sorted, key=itemgetter('name'))
সম্পূর্ণতার জন্য (ফিটজগেরাল্ডস্টিলের মন্তব্যে যেমন উল্লেখ করা হয়েছে), উতরাই reverse=True
বাছাই করতে যুক্ত করুন
newlist = sorted(l, key=itemgetter('name'), reverse=True)
itemgetter(i)
যেখানে i
উপর সাজাতে tuple উপাদান সূচি।
itemgetter
একাধিক যুক্তি গ্রহণ করে: itemgetter(1,2,3)
এটি এমন একটি ফাংশন যা একটি টুপলের মতো ফেরত দেয় obj[1], obj[2], obj[3]
, তাই আপনি জটিল প্রকারের জন্য এটি ব্যবহার করতে পারেন।
import operator
কীগুলির সাহায্যে অভিধানের তালিকা বাছাই করুন = 'নাম':
list_of_dicts.sort(key=operator.itemgetter('name'))
কী = 'বয়স' অনুসারে অভিধানের তালিকা সাজানোর জন্য:
list_of_dicts.sort(key=operator.itemgetter('age'))
key=lambda k: (k['name'], k['age'])
,। (বা key=itemgetter('name', 'age')
) টিপলগুলি cmp
প্রতিটি উপাদানকে পালাক্রমে তুলনা করবে। এটি রক্তাক্ত উজ্জ্বল।
key
যুক্তি list.sort()
বর্ণিত হয়নি। কোন ধারণা কোথায় এটি?
list
।
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'])
... ল্যাম্বদা আইএমও, এর চেয়ে বোঝা সহজ operator.itemgetter
, তবে ওয়াইএমএমভি।
আপনি যদি একাধিক কী দ্বারা তালিকাটি বাছাই করতে চান তবে নিম্নলিখিতগুলি করতে পারেন:
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']))
এটি বরং হ্যাকিশ, যেহেতু এটি তুলনার জন্য মানগুলিকে একক স্ট্রিং উপস্থাপনায় রূপান্তর করার উপর নির্ভর করে তবে এটি নেতিবাচকগুলি সহ সংখ্যার জন্য প্রত্যাশার মতো কাজ করে (যদিও আপনি সংখ্যাগুলি ব্যবহার করছেন তবে আপনার স্ট্রিংটি শূন্য প্যাডিংসের সাথে যথাযথভাবে ফর্ম্যাট করতে হবে)
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'])
আমার ধারণা আপনি বোঝাতে চেয়েছিলেন:
[{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}]
এটি এইভাবে বাছাই করা হবে:
sorted(l,cmp=lambda x,y: cmp(x['name'],y['name']))
আপনি একটি কাস্টম তুলনা ফাংশন ব্যবহার করতে পারেন, বা আপনি একটি কাস্টম বাছাই কী গণনা করে এমন একটি কার্যক্রমে পাস করতে পারেন। এটি সাধারণত আরও কার্যকরী হওয়ায় চাবিটি কেবলমাত্র আইটেম প্রতি একবার গণনা করা হয়, যখন তুলনা ফাংশনটিকে আরও অনেকবার ডাকা হবে।
আপনি এটি এইভাবে করতে পারেন:
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'))
পার্ল থেকে শোয়ার্তজিয়ান ট্রান্সফর্ম ব্যবহার করে,
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
কম্পিউটার সায়েন্সে শোয়ার্জিয়ান ট্রান্সফর্ম হ'ল পার্ল প্রোগ্রামিং আইডিয়াম যা আইটেমের তালিকা বাছাইয়ের দক্ষতা উন্নত করতে ব্যবহৃত হয়। এই আইডিয়োম তুলনামূলক ভিত্তিক বাছাইয়ের জন্য উপযুক্ত যখন অর্ডারটি আসলে উপাদানগুলির একটি নির্দিষ্ট সম্পত্তি (কী) এর ক্রমের উপর ভিত্তি করে থাকে, যেখানে সেই সম্পত্তিটি গণনা করা হয় নিবিড় ক্রিয়াকলাপ যা ন্যূনতম সংখ্যক বার করা উচিত। শোয়ার্জিয়ান ট্রান্সফর্মটি উল্লেখযোগ্য যে এটি নামযুক্ত অস্থায়ী অ্যারে ব্যবহার করে না।
key=
জন্য .sort
2.4 থেকে, বছর 2004 যে, এটা করে Schwartzian বাছাই কোড মধ্যেই সি রুপান্তর; সুতরাং এই পদ্ধতিটি কেবল পাইথনস ২.০-২.৩ এ কার্যকর is যার সবগুলিই 12 বছরেরও বেশি পুরানো।
আপনাকে নিজের তুলনা ফাংশনটি প্রয়োগ করতে হবে যা নাম কীগুলির মান অনুসারে অভিধানের তুলনা করবে। পাইথনইনফো উইকি থেকে মিনি-বাছাই করার পদ্ধতি দেখুন
কিছু সময় আমাদের 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}]
এখানে বিকল্প সাধারণ সমাধান রয়েছে - এটি কী এবং মান দ্বারা ডিকের উপাদানগুলি সাজায় s এর সুবিধা - কীগুলি নির্দিষ্ট করার দরকার নেই, এবং কিছু অভিধানে কিছু কী অনুপস্থিত থাকলে এটি এখনও কাজ করবে।
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)
পান্ডাস প্যাকেজটি ব্যবহার করা অন্য পদ্ধতি, যদিও এটি বড় আকারের রানটাইম অন্যদের প্রস্তাবিত প্রচলিত পদ্ধতির তুলনায় অনেক ধীরে ধীরে:
import pandas as pd
listOfDicts = [{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}]
df = pd.DataFrame(listOfDicts)
df = df.sort_values('name')
sorted_listOfDicts = df.T.to_dict().values()
একটি ক্ষুদ্র তালিকা এবং ডিক্টের বৃহত (100k +) তালিকার জন্য এখানে কিছু মানদণ্ডের মান রয়েছে:
setup_large = "listOfDicts = [];\
[listOfDicts.extend(({'name':'Homer', 'age':39}, {'name':'Bart', 'age':10})) for _ in range(50000)];\
from operator import itemgetter;import pandas as pd;\
df = pd.DataFrame(listOfDicts);"
setup_small = "listOfDicts = [];\
listOfDicts.extend(({'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}));\
from operator import itemgetter;import pandas as pd;\
df = pd.DataFrame(listOfDicts);"
method1 = "newlist = sorted(listOfDicts, key=lambda k: k['name'])"
method2 = "newlist = sorted(listOfDicts, key=itemgetter('name')) "
method3 = "df = df.sort_values('name');\
sorted_listOfDicts = df.T.to_dict().values()"
import timeit
t = timeit.Timer(method1, setup_small)
print('Small Method LC: ' + str(t.timeit(100)))
t = timeit.Timer(method2, setup_small)
print('Small Method LC2: ' + str(t.timeit(100)))
t = timeit.Timer(method3, setup_small)
print('Small Method Pandas: ' + str(t.timeit(100)))
t = timeit.Timer(method1, setup_large)
print('Large Method LC: ' + str(t.timeit(100)))
t = timeit.Timer(method2, setup_large)
print('Large Method LC2: ' + str(t.timeit(100)))
t = timeit.Timer(method3, setup_large)
print('Large Method Pandas: ' + str(t.timeit(1)))
#Small Method LC: 0.000163078308105
#Small Method LC2: 0.000134944915771
#Small Method Pandas: 0.0712950229645
#Large Method LC: 0.0321750640869
#Large Method LC2: 0.0206089019775
#Large Method Pandas: 5.81405615807
আপনি আসল প্রয়োজন না থাকে তাহলে list
এর dictionaries
, আপনি সাথে ইন-জায়গা এটি পরিবর্তন করতে পারে sort()
একটি কাস্টম কী ফাংশন ব্যবহার করে পদ্ধতি।
মূল ফাংশন:
def get_name(d):
""" Return the value of a key in a dictionary. """
return d["name"]
list
সাজানো হবে:
data_one = [{'name': 'Homer', 'age': 39}, {'name': 'Bart', 'age': 10}]
এটি স্থানে বাছাই করা হচ্ছে:
data_one.sort(key=get_name)
যদি আপনার আসল প্রয়োজন হয় list
তবে sorted()
ফাংশনটি এটি list
এবং কী ফাংশনটি পাস করে কল করুন , তারপরে রিটার্নটিকে সজ্জাটিকে list
একটি নতুন ভেরিয়েবল বরাদ্দ করুন :
data_two = [{'name': 'Homer', 'age': 39}, {'name': 'Bart', 'age': 10}]
new_data = sorted(data_two, key=get_name)
মুদ্রণ data_one
এবং new_data
।
>>> print(data_one)
[{'name': 'Bart', 'age': 10}, {'name': 'Homer', 'age': 39}]
>>> print(new_data)
[{'name': 'Bart', 'age': 10}, {'name': 'Homer', 'age': 39}]
ধরা যাক আমার D
নীচের উপাদানগুলির সাথে একটি অভিধান আছে । বাছাই করতে কেবল নীচের মত কাস্টম ফাংশনটি পাস করার জন্য বাছাই করে কী যুক্তি ব্যবহার করুন:
D = {'eggs': 3, 'ham': 1, 'spam': 2}
def get_count(tuple):
return tuple[1]
sorted(D.items(), key = get_count, reverse=True)
# or
sorted(D.items(), key = lambda x: x[1], reverse=True) # avoiding get_count function call
পরীক্ষা করে দেখুন এই বাইরে।
আমি ফিল্টার ডাব্লু / ল্যাম্বডায়ার একটি বড় অনুরাগী হয়ে উঠছি তবে আপনি সময়ের জটিলতা বিবেচনা করলে এটি সেরা বিকল্প নয়
প্রথম বিকল্প
sorted_list = sorted(list_to_sort, key= lambda x: x['name'])
# returns list of values
দ্বিতীয় বিকল্প
list_to_sort.sort(key=operator.itemgetter('name'))
#edits the list, does not return a new list
নির্বাহী সময়ের দ্রুত তুলনা
# First option
python3.6 -m timeit -s "list_to_sort = [{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}, {'name':'Faaa', 'age':57}, {'name':'Errr', 'age':20}]" -s "sorted_l=[]" "sorted_l = sorted(list_to_sort, key=lambda e: e['name'])"
1000000 লুপ, 3 লুপের প্রতি: 0.736 সর্বোত্তম c
# Second option
python3.6 -m timeit -s "list_to_sort = [{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}, {'name':'Faaa', 'age':57}, {'name':'Errr', 'age':20}]" -s "sorted_l=[]" -s "import operator" "list_to_sort.sort(key=operator.itemgetter('name'))"
1000000 লুপ, প্রতি লুপে 3: 0.438 ইউএসসি সেরা
পারফরম্যান্স যদি উদ্বেগের বিষয় থাকে তবে আমি হস্ত-কারুকৃত ফাংশনগুলির চেয়ে বিল্ট-ইন ফাংশনগুলি দ্রুত সম্পাদন করার operator.itemgetter
পরিবর্তে ব্যবহার করব lambda
। itemgetter
ফাংশন প্রায় 20% যতো তাড়াতাড়ি সঞ্চালন বলে মনে হয় lambda
আমার পরীক্ষার উপর ভিত্তি করে।
Https://wiki.python.org/moin/PythonSpeed থেকে :
তেমনি, বিল্টিন ফাংশনগুলি হস্তনির্মিত সমতুল্যের তুলনায় দ্রুত চলে। উদাহরণস্বরূপ, মানচিত্র (অপারেটর.এডিডি, ভি 1, ভি 2) মানচিত্রের চেয়ে দ্রুত (ল্যাম্বদা এক্স, ওয়াই: এক্স + ওয়াই, ভি 1, ভি 2)।
lambda
বনাম ব্যবহার করে বাছাইয়ের গতির তুলনা এখানে itemgetter
।
import random
import operator
# create a list of 100 dicts with random 8-letter names and random ages from 0 to 100.
l = [{'name': ''.join(random.choices(string.ascii_lowercase, k=8)), 'age': random.randint(0, 100)} for i in range(100)]
# Test the performance with a lambda function sorting on name
%timeit sorted(l, key=lambda x: x['name'])
13 µs ± 388 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
# Test the performance with itemgetter sorting on name
%timeit sorted(l, key=operator.itemgetter('name'))
10.7 µs ± 38.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
# Check that each technique produces same sort order
sorted(l, key=lambda x: x['name']) == sorted(l, key=operator.itemgetter('name'))
True
উভয় কৌশলই তালিকাটিকে একই ক্রমে বাছাই করে (কোড ব্লকে চূড়ান্ত বিবৃতি কার্যকর করে যাচাই করা হয়েছে) তবে একটিটি কিছুটা দ্রুত।
[{'name':'Bart', 'age':10, 'note':3},{'name':'Homer','age':10,'note':2},{'name':'Vasile','age':20,'note':3}]
এবং ব্যবহারের জন্য:from operator import itemgetter newlist = sorted(old_list, key=itemgetter(-'note','name')
সম্পাদনা: পরীক্ষিত, এবং এটি কাজ করছে তবে আমি কীভাবে নোট DESC করতে হবে এবং ASC নামকরণ করতে জানি না।