병렬 리스트의 해당 값에 따라 리스트 정렬
다음과 같은 문자열 목록이 있습니다.
X = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]
Y = [ 0, 1, 1, 0, 1, 2, 2, 0, 1 ]
다음 출력을 얻기 위해 Y의 값을 사용하여 X를 정렬하는 가장 빠른 방법은 무엇입니까?
["a", "d", "h", "b", "c", "e", "i", "f", "g"]
같은 「키」를 가지는 요소의 순서는 문제가 되지 않습니다.는 는는 i i i i i i i i i i i i i 。for
좀좀 더더 ?? ???은은 의견 ???
최단 코드
[x for _, x in sorted(zip(Y, X))]
예:
X = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]
Y = [ 0, 1, 1, 0, 1, 2, 2, 0, 1]
Z = [x for _,x in sorted(zip(Y,X))]
print(Z) # ["a", "d", "h", "b", "c", "e", "i", "f", "g"]
일반적으로 말하면
[x for _, x in sorted(zip(Y, X), key=lambda pair: pair[0])]
설명:
zip
두 사람list
s.- 정렬된 " " " 를 만듭니다.
list
에에에zip
를 사용합니다. - 목록 이해를 사용하여 정렬되고 압축된 각 쌍의 첫 번째 요소를 추출합니다.
list
.
「 」의 는, 「 」를 해 .key
와 '''를 지정합니다.sorted
일반적인 기능, 이것 좀 보세요.
두 목록을 함께 압축하고 정렬한 다음 원하는 부품을 가져옵니다.
>>> yx = zip(Y, X)
>>> yx
[(0, 'a'), (1, 'b'), (1, 'c'), (0, 'd'), (1, 'e'), (2, 'f'), (2, 'g'), (0, 'h'), (1, 'i')]
>>> yx.sort()
>>> yx
[(0, 'a'), (0, 'd'), (0, 'h'), (1, 'b'), (1, 'c'), (1, 'e'), (1, 'i'), (2, 'f'), (2, 'g')]
>>> x_sorted = [x for y, x in yx]
>>> x_sorted
['a', 'd', 'h', 'b', 'c', 'e', 'i', 'f', 'g']
이것들을 조합하면, 다음과 같이 됩니다.
[x for y, x in sorted(zip(Y, X))]
또한 numpy 어레이를 사용해도 괜찮으시다면(또는 이미 numpy 어레이를 사용하고 있습니다) 또 다른 좋은 솔루션이 있습니다.
people = ['Jim', 'Pam', 'Micheal', 'Dwight']
ages = [27, 25, 4, 9]
import numpy
people = numpy.array(people)
ages = numpy.array(ages)
inds = ages.argsort()
sortedPeople = people[inds]
http://scienceoss.com/sort-one-list-by-another-list/에서 찾았습니다.
은 '아, 아, 아, 아,key
arg.
>>> X = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]
>>> Y = [ 0, 1, 1, 0, 1, 2, 2, 0, 1]
>>> keydict = dict(zip(X, Y))
>>> X.sort(key=keydict.get)
>>> X
['a', 'd', 'h', 'b', 'c', 'e', 'i', 'f', 'g']
다음의 경우에, 이것을 원라이너로 단축할 수 있습니다.
>>> X.sort(key=dict(zip(X, Y)).get)
원민무와 잭 펑이 지적한 바와 같이, 이것은 그 가치들이 다음과 같이 가정한다.X
모두 구별됩니다.인덱스 목록을 사용하여 쉽게 관리할 수 있습니다.
>>> Z = ["A", "A", "C", "C", "C", "F", "G", "H", "I"]
>>> Z_index = list(range(len(Z)))
>>> Z_index.sort(key=keydict.get)
>>> Z = [Z[i] for i in Z_index]
>>> Z
['A', 'C', 'H', 'A', 'C', 'C', 'I', 'F', 'G']
Whatang이 설명한 데코레이션-소트-언데코레이션 접근법은 조금 더 간단하고 모든 경우에 적용되기 때문에 대부분의 경우 더 나을 수 있습니다.(이것은 매우 오래된 대답입니다!)
more_itertools
에는 반복가능성을 병렬로 정렬하는 도구가 있습니다.
정해진
from more_itertools import sort_together
X = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]
Y = [ 0, 1, 1, 0, 1, 2, 2, 0, 1]
데모
sort_together([Y, X])[1]
# ('a', 'd', 'h', 'b', 'c', 'e', 'i', 'f', 'g')
저는 실제로 값이 일치하는 목록별로 목록을 정렬하기 위해 여기에 왔습니다.
list_a = ['foo', 'bar', 'baz']
list_b = ['baz', 'bar', 'foo']
sorted(list_b, key=lambda x: list_a.index(x))
# ['foo', 'bar', 'baz']
또 다른 대안으로, 몇 가지 답을 조합할 수 있습니다.
zip(*sorted(zip(Y,X)))[1]
python3에서 작업하려면:
list(zip(*sorted(zip(B,A))))[1]
나는 정렬된 색인 목록이 있는 것을 좋아한다.그러면 소스 목록과 같은 순서로 목록을 정렬할 수 있습니다.정렬된 인덱스 목록이 있으면 간단한 목록 이해로 다음과 같은 작업을 수행할 수 있습니다.
X = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]
Y = [ 0, 1, 1, 0, 1, 2, 2, 0, 1]
sorted_y_idx_list = sorted(range(len(Y)),key=lambda x:Y[x])
Xs = [X[i] for i in sorted_y_idx_list ]
print( "Xs:", Xs )
# prints: Xs: ["a", "d", "h", "b", "c", "e", "i", "f", "g"]
는 또한 렬음음음음음음음음음음음음음음음음음음음음 note note note note note note를 사용하여 얻을 .numpy.argsort()
.
zip, 두 번째 열로 정렬하고 첫 번째 열을 반환합니다.
zip(*sorted(zip(X,Y), key=operator.itemgetter(1)))[0]
이지만, 가 본 중 몇는 실제로 zip
스크립팅할 수 없습니다. 치 않았다import operator
및 이 모듈 및 이점에 대한 자세한 내용은 여기를 참조하십시오.
이 문제에 대해 적어도 두 가지 좋은 관용구가 있습니다.입력한 예부터 시작합니다.
X = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]
Y = [ 0, 1, 1, 0, 1, 2, 2, 0, 1 ]
"Decorate-Sort-Undecorate" 관용어 사용
이것은 R의 이름을 따서 Schwartzian_transform이라고도 합니다. 90년대에 Perl에서 이 패턴을 보급한 Schwartz:
# Zip (decorate), sort and unzip (undecorate).
# Converting to list to script the output and extract X
list(zip(*(sorted(zip(Y,X)))))[1]
# Results in: ('a', 'd', 'h', 'b', 'c', 'e', 'i', 'f', 'g')
, 「」는 다음과 .Y
★★★★★★★★★★★★★★★★★」X
이치노 첫 항목(「」, 「」의 항목(「」로부터)Y
두 항목: 두 번째 항목)입니다(출처)X
)을 비교하는 등의 작업을 실시합니다.이렇게 하면 중복된 내용을 원래 순서로 유지하기 위해 사전 정렬 순서에 대한 원래 목록 인덱스를 포함하지 않는 한 출력이 불안정해질 수 있습니다.
모듈 사용
이것에 의해, 입력의 정렬 방법을 보다 직접적으로 제어할 수 있기 때문에, 소트 기준의 특정의 키를 말하는 것만으로, 소트 안정성을 얻을 수 있습니다.자세한 예는 이쪽을 참조해 주세요.
import operator
# Sort by Y (1) and extract X [0]
list(zip(*sorted(zip(X,Y), key=operator.itemgetter(1))))[0]
# Results in: ('a', 'd', 'h', 'b', 'c', 'e', 'i', 'f', 'g')
만들 수 요.pandas Series
를 「」로서 data
는 '''로 되어 있습니다.index
이치노
import pandas as pd
pd.Series(data=X,index=Y).sort_index().tolist()
출력:
['a', 'd', 'h', 'b', 'c', 'e', 'i', 'f', 'g']
퀵 원라이너
list_a = [5,4,3,2,1]
list_b = [1,1.5,1.75,2,3,3.5,3.75,4,5]
리스트 a와 리스트 b를 일치시키고 싶다고 합니다.
orderedList = sorted(list_a, key=lambda x: list_b.index(x))
이것은 작은 목록을 큰 값으로 주문해야 할 때 유용합니다.큰 목록이 작은 목록의 모든 값을 포함한다고 가정하면 이 작업을 수행할 수 있습니다.
정렬된 목록(python3)을 모두 가져오고 싶은 경우 Whatangs는 다음과 같이 답변합니다.
X = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]
Y = [ 0, 1, 1, 0, 1, 2, 2, 0, 1]
Zx, Zy = zip(*[(x, y) for x, y in sorted(zip(Y, X))])
print(list(Zx)) # [0, 0, 0, 1, 1, 1, 1, 2, 2]
print(list(Zy)) # ['a', 'd', 'h', 'b', 'c', 'e', 'i', 'f', 'g']
Zx와 Zy는 튜플이라는 것만 기억하세요.더 좋은 방법이 없을까 망설이고 있어요.
경고:빈 목록을 사용하여 실행하면 크래시됩니다.
저는 @Whatang의 답변에서 영감을 얻어 다른 목록을 기준으로 두 개 이상의 목록을 정렬하는 보다 일반적인 기능을 만들었습니다.
def parallel_sort(*lists):
"""
Sorts the given lists, based on the first one.
:param lists: lists to be sorted
:return: a tuple containing the sorted lists
"""
# Create the initially empty lists to later store the sorted items
sorted_lists = tuple([] for _ in range(len(lists)))
# Unpack the lists, sort them, zip them and iterate over them
for t in sorted(zip(*lists)):
# list items are now sorted based on the first list
for i, item in enumerate(t): # for each item...
sorted_lists[i].append(item) # ...store it in the appropriate list
return sorted_lists
X = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]
Y = [ 0, 1, 1, 0, 1, 2, 2, 0, 1 ]
이 작업은 한 줄로 수행할 수 있습니다.
X, Y = zip(*sorted(zip(Y, X)))
이 기능은 어레이에 대해 동작합니다.
def sortBoth(x,y,reverse=False):
'''
Sort both x and y, according to x.
'''
xy_sorted=array(sorted(zip(x,y),reverse=reverse)).T
return xy_sorted[0],xy_sorted[1]
위의 두 가지 리스트의 사이즈가 다르거나 아이템이 다르면 대부분의 솔루션이 작동하지 않을 것입니다.다음 솔루션은 단순하며 이러한 문제를 해결할 수 있습니다.
import pandas as pd
list1 = ['B', 'A', 'C'] # Required sort order
list2 = ['C', 'A'] # Items to be sorted according to list1
result = pd.merge(pd.DataFrame(list1), pd.DataFrame(list2))
print(list(result[0]))
출력:
['A', 'C']
- 주의: list1에 없는 항목은 알고리즘이 사용하는 정렬 순서를 알 수 없으므로 무시됩니다.
list1 = ['a','b','c','d','e','f','g','h','i']
list2 = [0,1,1,0,1,2,2,0,1]
output=[]
cur_loclist = []
고유한 값을 가져오려면list2
list_set = set(list2)
에서 인덱스 위치를 찾으려면list2
list_str = ''.join(str(s) for s in list2)
의 인덱스 위치list2
를 사용하여 추적합니다.cur_loclist
[0, 3, 7, 1, 2, 4, 8, 5, 6]
for i in list_set:
cur_loc = list_str.find(str(i))
while cur_loc >= 0:
cur_loclist.append(cur_loc)
cur_loc = list_str.find(str(i),cur_loc+1)
print(cur_loclist)
for i in range(0,len(cur_loclist)):
output.append(list1[cur_loclist[i]])
print(output)
위의 해결방법은 대부분 복잡하기 때문에 리스트의 길이가 다르거나 동일한 항목이 포함되지 않으면 효과가 없을 것입니다.아래 솔루션은 단순하며 Import가 필요하지 않습니다.
list1 = ['B', 'A', 'C'] # Required sort order
list2 = ['C', 'B'] # Items to be sorted according to list1
result = list1
for item in list1:
if item not in list2: result.remove(item)
print(result)
출력:
['B', 'C']
- 주의: list1에 없는 항목은 알고리즘이 사용하는 정렬 순서를 알 수 없으므로 무시됩니다.
나는 원래 질문의 제목이 정확하지 않다고 생각한다.항목 수가 동일한 목록이 2개 있고 목록 1의 모든 항목이 목록 2와 동일한 순서로 관련되는 경우(예: a = 0, b = 1 등), 질문은 '다른 목록의 값을 기준으로 목록을 정렬하는 방법'이 아니라 '사전 정렬 방법'이어야 합니다.이 경우 다음 솔루션이 가장 효율적입니다.
X = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]
Y = [ 0, 1, 1, 0, 1, 2, 2, 0, 1 ]
dict1 = dict(zip(X,Y))
result = sorted(dict1, key=dict1.get)
print(result)
결과:
['a', 'd', 'h', 'b', 'c', 'e', 'i', 'f', 'g']
언급URL : https://stackoverflow.com/questions/6618515/sorting-list-according-to-corresponding-values-from-a-parallel-list
'programing' 카테고리의 다른 글
바인딩 변환기 매개 변수 (0) | 2023.04.10 |
---|---|
git 오류: 일부 참조를 원격으로 푸시하지 못했습니다. (0) | 2023.04.10 |
iPhone에서 사용자가 푸시 알림을 활성화했는지 확인합니다. (0) | 2023.04.10 |
How to create a link inside a cell using EPPlus (0) | 2023.04.10 |
bash 스크립트에서 파일 이름 확장자를 확인하는 방법 (0) | 2023.04.10 |