development

다른 목록의 값을 기준으로 목록을 정렬 하시겠습니까?

big-blog 2020. 3. 15. 09:40
반응형

다른 목록의 값을 기준으로 목록을 정렬 하시겠습니까?


다음과 같은 문자열 목록이 있습니다.

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

동일한 "키"를 갖는 요소의 순서는 중요하지 않습니다. 나는 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])]

설명 :

  1. ziplists.
  2. using을 list기준으로 정렬 된 새 것을 만듭니다 .zipsorted()
  3. list comprehension을 사용 하여 sorted, zipped에서 각 쌍의 첫 번째 요소를 추출 하십시오 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 = ["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"]

정렬 된 인덱스 목록은을 사용하여 얻을 수도 있습니다 numpy.argsort().


또 다른 대안은 여러 답변을 결합한 것입니다.

zip(*sorted(zip(Y,X)))[1]

python3에서 작동하려면 :

list(zip(*sorted(zip(B,A))))[1]

실제로 값이 일치하는 목록을 기준으로 목록을 정렬하려고했습니다.

list_a = ['foo', 'bar', 'baz']
list_b = ['baz', 'bar', 'foo']
sorted(list_b, key=lambda x: list_a.index(x))
# ['foo', 'bar', 'baz']

more_itertools iterable을 병렬로 정렬하는 도구가 있습니다.

from more_itertools import sort_together


sort_together([Y, X])[1]
# ('a', 'd', 'h', 'b', 'c', 'e', 'i', 'f', 'g')

zip은 두 번째 열을 기준으로 정렬하여 첫 번째 열을 반환합니다.

zip(*sorted(zip(X,Y), key=operator.itemgetter(1)))[0]

빠른 원 라이너.

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

작은 목록을 큰 값으로 주문해야 할 때 유용합니다. 큰 목록에 작은 목록의 모든 값이 포함되어 있다고 가정하면 수행 할 수 있습니다.


당신은을 만들 수 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']

정렬 된 목록 (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

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)

참고 URL : https://stackoverflow.com/questions/6618515/sorting-list-based-on-values-from-another-list

반응형