병렬 목록이 주어지면 다른 목록을 동일한 방식으로 순열(재배치)하면서 하나를 정렬하려면 어떻게 해야 합니까?
내가 가지고 있다고 가정해보자면
list1 = [3, 2, 4, 1, 1]
list2 = ['three', 'two', 'four', 'one', 'one2']
하기 르기list1.sort()
정하여결로으과적렬로▁in▁will[1, 1, 2, 3, 4]
하지만, 제가 받을 수 있을까요?list2
그것과 동기화되어 재배치되는 것, 이런 결과를 얻는 것?
list1 = [1, 1, 2, 3, 4]
list2 = ['one', 'one2', 'two', 'three', 'four']
때때로 사람들은 문제를 다르게 표현합니다. 두 개의 목록이 주어지면 하나를 사용하여 다른 목록의 정렬 순서를 결정하려고 합니다. 즉, 정렬list2
값로 순대 로서설의 해당 값으로 list1
비결은 이것이 "키" 값을 정렬하는 것과 같다는 것입니다.list1
), 정렬합니다.list2
같은방로으법▁ 다시 되어 있는 입니다.다시 말해, 여기에 설명된 것과 정확히 일치합니다.그러나 다른 질문에 대한 일부 대답은 나중에 "정렬된 키"를 폐기합니다.
참고 항목:다른 목록에서 해당 구성요소가 나타나는 위치에 따라 목록을 정렬하려면 어떻게 해야 합니까? - 이것은 사용자가 한 목록을 다른 목록을 기준으로 정렬하려는 또 다른 일반적인 방법입니다.중복 질문을 닫기 전에 OP가 정확히 무엇을 원하는지 특별히 주의해야 합니다.핵심 단서: 목록의 길이가 같아야 합니까?
한 인 접근법은 ", 파이썬의 된 이에제인접근중 "decorate, sort, undecorate"를 하는 것입니다.zip
함수:
>>> list1 = [3,2,4,1, 1]
>>> list2 = ['three', 'two', 'four', 'one', 'one2']
>>> list1, list2 = zip(*sorted(zip(list1, list2)))
>>> list1
(1, 1, 2, 3, 4)
>>> list2
('one', 'one2', 'two', 'three', 'four')
물론 이러한 목록은 더 이상 존재하지 않지만 다음과 같은 문제가 발생할 경우 쉽게 해결할 수 있습니다.
>>> list1, list2 = (list(t) for t in zip(*sorted(zip(list1, list2))))
>>> list1
[1, 1, 2, 3, 4]
>>> list2
['one', 'one2', 'two', 'three', 'four']
위의 내용이 간결함을 위해 속도를 희생할 수 있다는 점에 주목할 필요가 있습니다. 3줄을 차지하는 인플레이스 버전은 작은 목록을 위해 제 컴퓨터에서 조금 더 빠릅니다.
>>> %timeit zip(*sorted(zip(list1, list2)))
100000 loops, best of 3: 3.3 us per loop
>>> %timeit tups = zip(list1, list2); tups.sort(); zip(*tups)
100000 loops, best of 3: 2.84 us per loop
반면에 목록이 큰 경우 한 줄 버전이 더 빠를 수 있습니다.
>>> %timeit zip(*sorted(zip(list1, list2)))
100 loops, best of 3: 8.09 ms per loop
>>> %timeit tups = zip(list1, list2); tups.sort(); zip(*tups)
100 loops, best of 3: 8.51 ms per loop
Quantum7이 지적했듯이, JSF의 제안은 여전히 약간 빠르지만, Python은 모든 키 기반 정렬에 대해 내부적으로 동일한 DSU 관용구를 사용하기 때문에 아마도 조금 더 빠를 것입니다.그것은 단지 금속에 조금 더 가까운 곳에서 일어나고 있을 뿐입니다.(이것은 얼마나 잘 최적화되었는지를 보여줍니다.zip
루틴은!)
제 생각엔zip
기반 접근 방식이 더 유연하고 조금 더 읽기 쉬우므로 선호합니다.
참고로 다음의 요소가 있을 수 있습니다.list1
경우, 이 동경한우방, 접은결다요국음비될다의 하게 될 입니다.list2
요소인경의 list2
때 if if 비지원지않예때생부않습성니다지하을울교비를할: if: if).list2
배열 하며, NumPy 배 목 록 열 며 것 이 요 들 이 소 만 약 할 이 패실의 실패합니다.list2
비교하는 데 매우 비용이 많이 듭니다. 어쨌든 비교는 피하는 것이 더 나을 수 있습니다.
jfs의하거나, 의이jfs답제대정인나, 정요비를않의 키 할 수 .list2
:
result1, result2 = zip(*sorted(zip(list1, list2), key=lambda x: x[0]))
한또, 의용의 .zip(*...)
입력이 비어 있을 때 전치가 실패하기 때문입니다.입력한 내용이 비어 있을 수 있는 경우 해당 사례를 별도로 처리해야 합니다.
값을 키로 사용하여 인덱스를 정렬할 수 있습니다.
indexes = range(len(list1))
indexes.sort(key=list1.__getitem__)
정렬된 인덱스가 지정된 정렬된 목록을 가져오는 방법
sorted_list1 = map(list1.__getitem__, indexes)
sorted_list2 = map(list2.__getitem__, indexes)
당신의 경우에는, 당신은 하지 말았어야 했어요.list1
,list2
쌍의 단일 목록:
data = [(3, 'three'), (2, 'two'), (4, 'four'), (1, 'one'), (1, 'one2')]
Python에서 쉽게 만들 수 있고 정렬할 수 있습니다.
data.sort() # sort using a pair as a key
첫 번째 값만 기준으로 정렬:
data.sort(key=lambda pair: pair[0])
준을 제가 .np.argsort
작동 방식은 다음과 같습니다.
# idx works on np.array and not lists.
list1 = np.array([3,2,4,1])
list2 = np.array(["three","two","four","one"])
idx = np.argsort(list1)
list1 = np.array(list1)[idx]
list2 = np.array(list2)[idx]
저는 이 해결책이 더 직관적이라고 생각합니다. 그리고 그것은 정말 잘 작동합니다.성능:
def sorting(l1, l2):
# l1 and l2 has to be numpy arrays
idx = np.argsort(l1)
return l1[idx], l2[idx]
# list1 and list2 are np.arrays here...
%timeit sorting(list1, list2)
100000 loops, best of 3: 3.53 us per loop
# This works best when the lists are NOT np.array
%timeit zip(*sorted(zip(list1, list2)))
100000 loops, best of 3: 2.41 us per loop
# 0.01us better for np.array (I think this is negligible)
%timeit tups = zip(list1, list2); tups.sort(); zip(*tups)
100000 loops, best for 3 loops: 1.96 us per loop
그럼에도 불구하고.np.argsort
가장 빠른 것이 아닙니다. 사용하기가 더 쉽다는 것을 합니다.
이것은 Perl 프로그래머들이 decorate-sort-undecorate 관용구로도 알려진 Schwartzian 변환이라고 부르는 것을 사용하여 수행될 수 있습니다.내장된 Python 정렬은 안정적이므로 두 가지는1
문제를 일으키지 마십시오.
>>> l1 = [3, 2, 4, 1, 1]
>>> l2 = ['three', 'two', 'four', 'one', 'second one']
>>> zip(*sorted(zip(l1, l2)))
[(1, 1, 2, 3, 4), ('one', 'second one', 'two', 'three', 'four')]
당신은 할 수 .zip()
그리고.sort()
이를 위한 기능:
Python 2.6.5 (r265:79063, Jun 12 2010, 17:07:01)
[GCC 4.3.4 20090804 (release) 1] on cygwin
>>> list1 = [3,2,4,1,1]
>>> list2 = ['three', 'two', 'four', 'one', 'one2']
>>> zipped = zip(list1, list2)
>>> zipped.sort()
>>> slist1 = [i for (i, s) in zipped]
>>> slist1
[1, 1, 2, 3, 4]
>>> slist2 = [s for (i, s) in zipped]
>>> slist2
['one', 'one2', 'two', 'three', 'four']
이것이 도움이 되길 바랍니다.
한 가지 방법은 ID [0,1,2,...n]를 정렬하여 각 인덱스가 어디로 가는지 추적하는 것입니다.
이것은 임의의 수의 목록에 대해 작동합니다.
그런 다음 각 항목을 해당 위치로 이동합니다.스플라이스를 사용하는 것이 가장 좋습니다.
list1 = [3,2,4,1, 1]
list2 = ['three', 'two', 'four', 'one', 'one2']
index = list(range(len(list1)))
print(index)
'[0, 1, 2, 3, 4]'
index.sort(key = list1.__getitem__)
print(index)
'[3, 4, 1, 0, 2]'
list1[:] = [list1[i] for i in index]
list2[:] = [list2[i] for i in index]
print(list1)
print(list2)
'[1, 1, 2, 3, 4]'
"['one', 'one2', 'two', 'three', 'four']"
목록을 정렬하지 않고도 반복할 수 있습니다.
list1_iter = (list1[i] for i in index)
다음은 어떻습니까?
list1 = [3,2,4,1, 1]
list2 = ['three', 'two', 'four', 'one', 'one2']
sortedRes = sorted(zip(list1, list2), key=lambda x: x[0]) # use 0 or 1 depending on what you want to sort
>>> [(1, 'one'), (1, 'one2'), (2, 'two'), (3, 'three'), (4, 'four')]
이 numpy를 한다면, 은 numpy를 사용할 수 .np.argsort
정렬된 인덱스를 가져와 해당 인덱스를 목록에 적용합니다.이 옵션은 정렬할 목록의 수에 관계없이 사용할 수 있습니다.
import numpy as np
arr1 = np.array([4,3,1,32,21])
arr2 = arr1 * 10
sorted_idxs = np.argsort(arr1)
print(sorted_idxs)
>>> array([2, 1, 0, 4, 3])
print(arr1[sorted_idxs])
>>> array([ 1, 3, 4, 21, 32])
print(arr2[sorted_idxs])
>>> array([ 10, 30, 40, 210, 320])
list2에 두 개의 동일한 값이 없는 한 sorted() 메서드에서 key 인수를 사용할 수 있습니다.
코드는 다음과 같습니다.
sorted(list2, key = lambda x: list1[list2.index(x)])
list.index() 함수는 list.index() 함수가 첫 번째 값을 제공하므로 list1의 해당 값에 따라 list2를 정렬하지만 이 값을 사용하는 동안 list2의 두 값이 동일하게 평가되지 않도록 합니다.
다른 목록을 기준으로 정렬할 때 문자열 목록의 순서를 유지하는 또 다른 방법은 다음과 같습니다.
list1 = [3,2,4,1, 1]
list2 = ['three', 'two', 'four', 'one', 'one2']
# sort on list1 while retaining order of string list
sorted_list1 = [y for _,y in sorted(zip(list1,list2),key=lambda x: x[0])]
sorted_list2 = sorted(list1)
print(sorted_list1)
print(sorted_list2)
산출량
['one', 'one2', 'two', 'three', 'four']
[1, 1, 2, 3, 4]
두 개 이상의 목록을 동시에 정렬해야 할 경우 해결책을 제안하고자 합니다.
def SortAndSyncList_Multi(ListToSort, *ListsToSync):
y = sorted(zip(ListToSort, zip(*ListsToSync)))
w = [n for n in zip(*y)]
return list(w[0]), tuple(list(a) for a in zip(*w[1]))
저는 제 문제에 큰 도움이 된 open jfs의 답변을 확장하고 싶습니다: 세 번째로 장식된 목록으로 두 개의 목록을 정렬합니다.
우리는 어떤 식으로든 장식된 목록을 만들 수 있지만, 이 경우에는 원래 목록 두 개 중 하나의 요소를 사용하여 정렬할 수 있습니다.
# say we have the following list and we want to sort both by the algorithms name
# (if we were to sort by the string_list, it would sort by the numerical
# value in the strings)
string_list = ["0.123 Algo. XYZ", "0.345 Algo. BCD", "0.987 Algo. ABC"]
dict_list = [{"dict_xyz": "XYZ"}, {"dict_bcd": "BCD"}, {"dict_abc": "ABC"}]
# thus we need to create the decorator list, which we can now use to sort
decorated = [text[6:] for text in string_list]
# decorated list to sort
>>> decorated
['Algo. XYZ', 'Algo. BCD', 'Algo. ABC']
이제 JFS 솔루션을 적용하여 세 번째로 두 목록을 정렬할 수 있습니다.
# create and sort the list of indices
sorted_indices = list(range(len(string_list)))
sorted_indices.sort(key=decorated.__getitem__)
# map sorted indices to the two, original lists
sorted_stringList = list(map(string_list.__getitem__, sorted_indices))
sorted_dictList = list(map(dict_list.__getitem__, sorted_indices))
# output
>>> sorted_stringList
['0.987 Algo. ABC', '0.345 Algo. BCD', '0.123 Algo. XYZ']
>>> sorted_dictList
[{'dict_abc': 'ABC'}, {'dict_bcd': 'BCD'}, {'dict_xyz': 'XYZ'}]
newsource=[];newtarget=[]
for valueT in targetFiles:
for valueS in sourceFiles:
l1=len(valueS);l2=len(valueT);
j=0
while (j< l1):
if (str(valueT) == valueS[j:l1]) :
newsource.append(valueS)
newtarget.append(valueT)
j+=1
알고리즘 솔루션:
list1 = [3,2,4,1, 1]
list2 = ['three', 'two', 'four', 'one', 'one2']
lis = [(list1[i], list2[i]) for i in range(len(list1))]
list1.sort()
list2 = [x[1] for i in range(len(list1)) for x in lis if x[0] == i]
출력: ->
출력 속도: 0.2s
>>>list1
>>>[1, 1, 2, 3, 4]
>>>list2
>>>['one', 'one2', 'two', 'three', 'four']
방금 닫은 중복 질문에 대한 @pylang의 답변을 기반으로 인기 있는 타사 라이브러리에서 필요한 알고리즘을 구현합니다.more_itertools
하나로
따라서:
from more_itertools import sort_together
list1 = [3, 2, 4, 1, 1]
list2 = ['three', 'two', 'four', 'one', 'one2']
list1, list2 = sort_together(list1, list2)
python(십진수 값으로 정렬됨)에서 두 개의 ListParlerly 정렬
a = ['a','b','c','d','e','f']
b = ['0.23','80.00','5.01','6.58','1.38','79.06']
c=sorted(b,key=lambda x:float(x))
d=[]
for i in range(len(a)):
d.append(a[b.index(c[i])])
언급URL : https://stackoverflow.com/questions/9764298/given-parallel-lists-how-can-i-sort-one-while-permuting-rearranging-the-other
'source' 카테고리의 다른 글
두 NSD 날짜를 비교하는 방법어느 것이 더 최근입니까? (0) | 2023.04.26 |
---|---|
Android Studio 프로젝트의 .gitignore에는 무엇이 있어야 합니까? (0) | 2023.04.26 |
모든 Git 태그를 나열하는 방법? (0) | 2023.04.26 |
Eclipse - 라인 번호 속성이 누락되어 중단점을 설치할 수 없습니다. (0) | 2023.04.26 |
AWS S3 CLI를 사용하여 BASH에서 stdout으로 파일을 덤프하는 방법은 무엇입니까? (0) | 2023.04.26 |