etc./StackOverFlow

사전 값으로 사전 목록을 정렬하려면 어떻게 해야 합니까?

청렴결백한 만능 재주꾼 2021. 11. 26. 06:55
반응형

질문자 :Community Wiki


사전 목록이 있고 각 항목을 특정 값으로 정렬하기를 원합니다.

다음 목록을 고려하십시오.

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

name 으로 정렬하면 다음과 같아야 합니다.

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


sorted() key= 매개변수를 취합니다.

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

또는 함수를 직접 정의하는 대신 operator.itemgetter 를 사용할 수 있습니다.

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

완전성을 위해 reverse=True 를 추가하여 내림차순으로 정렬합니다.

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

Mario F

import operator

key='name'으로 사전 목록을 정렬하려면:

 list_of_dicts.sort(key=operator.itemgetter('name'))

key='age'로 사전 목록을 정렬하려면:

 list_of_dicts.sort(key=operator.itemgetter('age'))

vemury

my_list = [{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}] my_list.sort(lambda x,y : cmp(x['name'], y['name']))

my_list 가 원하는 대로 될 것입니다.

또는 더 나은:

Python 2.4 이후로 더 효율적이고 깔끔하다는 key

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

...람다는 IMO로 operator.itemgetter 보다 이해하기 쉽지만 마일리지는 다를 수 있습니다.


pjz

여러 키로 목록을 정렬하려면 다음을 수행할 수 있습니다.

 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']))

비교를 위해 값을 단일 문자열 표현으로 변환하는 것에 의존하기 때문에 다소 엉뚱하지만 음수를 포함한 숫자에 대해서는 예상대로 작동합니다(단, 숫자를 사용하는 경우 패딩 없이 문자열 형식을 적절하게 지정해야 함).


Community Wiki

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'])

Community Wiki

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

'key'는 임의의 값으로 정렬하는 데 사용되며 'itemgetter'는 해당 값을 각 항목의 'name' 속성으로 설정합니다.


efotinis

나는 당신이 의미 한 것 같아요 :

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

이것은 다음과 같이 정렬됩니다.

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

Bartosz Radaczyński

사용자 정의 비교 함수를 사용하거나 사용자 정의 정렬 키를 계산하는 함수를 전달할 수 있습니다. 키는 항목당 한 번만 계산되는 반면 비교 기능은 더 많이 호출되기 때문에 일반적으로 더 효율적입니다.

다음과 같이 할 수 있습니다.

 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'))

Owen

Perl 의 Schwartzian 변환 을 사용하여,

 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'}]

Perl Schwartzian 변환에 대한 추가 정보:

컴퓨터 과학에서 Schwartzian 변환은 항목 목록 정렬의 효율성을 향상시키는 데 사용되는 Perl 프로그래밍 관용구입니다. 이 관용구는 순서가 실제로 요소의 특정 속성(키)의 순서를 기반으로 하는 경우 비교 기반 정렬에 적합합니다. 여기서 해당 속성을 계산하는 것은 최소 횟수로 수행되어야 하는 집중 작업입니다. Schwartzian Transform은 명명된 임시 배열을 사용하지 않는다는 점에서 주목할 만합니다.


Community Wiki

이름 키 값으로 사전을 비교하는 고유한 비교 기능을 구현해야 합니다. PythonInfo Wiki에서 Mini-HOW TO 정렬 참조


Matej

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}]

Community Wiki

Pandas 패키지를 사용하는 것도 또 다른 방법이지만 대규모 런타임은 다른 사람들이 제안한 기존 방법보다 훨씬 느립니다.

 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

Community Wiki

다음은 대체 일반 솔루션입니다. dict의 요소를 키와 값으로 정렬합니다.

장점 - 키를 지정할 필요가 없으며 일부 사전에서 일부 키가 누락된 경우에도 여전히 작동합니다.

 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)

Community Wiki

dictionaries list 이 필요하지 않은 경우 사용자 정의 키 기능을 사용하여 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 이 필요한 경우 list 과 키 함수를 전달하는 sorted() 함수를 호출한 다음 반환된 정렬된 list 을 새 변수에 할당합니다.

 data_two = [{'name': 'Homer', 'age': 39}, {'name': 'Bart', 'age': 10}] new_data = sorted(data_two, key=get_name)

data_onenew_data 인쇄 중.

 >>> print(data_one) [{'name': 'Bart', 'age': 10}, {'name': 'Homer', 'age': 39}] >>> print(new_data) [{'name': 'Bart', 'age': 10}, {'name': 'Homer', 'age': 39}]

Community Wiki

아래 요소 D 가 있다고 가정해 보겠습니다. sorted 에서 키 인수를 사용하여 아래와 같이 사용자 정의 함수를 전달하십시오.

 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

이것을 확인하십시오.


Community Wiki

나는 람다가 있는 필터의 열렬한 팬이었습니다. 그러나 시간 복잡도를 고려하면 최선의 선택은 아닙니다.

첫 번째 옵션

 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, and 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 µsec

 # 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 µsec


Community Wiki

성능이 문제라면 내장 함수가 손으로 만든 함수보다 빠르게 수행되므로 lambda 대신 operator.itemgetter itemgetter 함수는 내 테스트를 기반으로 lambda 보다 약 20% 더 빠르게 수행되는 것 같습니다.

https://wiki.python.org/moin/PythonSpeed에서 :

마찬가지로 내장 함수는 손으로 만든 함수보다 빠르게 실행됩니다. 예를 들어 map(operator.add, v1, v2)은 map(lambda x,y: x+y, v1, v2)보다 빠릅니다.

lambdaitemgetter 사용한 정렬 속도의 비교입니다.

 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 the same sort order sorted(l, key=lambda x: x['name']) == sorted(l, key=operator.itemgetter('name')) True

두 기술 모두 동일한 순서로 목록을 정렬하지만(코드 블록의 최종 명령문 실행으로 확인) 첫 번째 기술이 조금 더 빠릅니다.


Community Wiki

이 답변의 주석 섹션에서 @Claudiu가 @monojohnny에게 표시한 것처럼 ,
주어진:

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

'age' , 'name' 키를 기준으로 사전 목록을 정렬하려면
(SQL 문 ORDER BY age, name 에서처럼) 다음을 사용할 수 있습니다.

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

또는 마찬가지로

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

print(newlist)

[{'이름': '바트', '나이': 10},
{'이름': '밀하우스', '나이': 10},
{'이름': '호머', '나이': 39}]


Community Wiki

출처 : http:www.stackoverflow.com/questions/72899/how-do-i-sort-a-list-of-dictionaries-by-a-value-of-the-dictionary

반응형