상세 컨텐츠

본문 제목

sort, sorted

Python

by techbard 2024. 12. 4. 18:19

본문

반응형

 

# How is it different than the sort list method?
# - List sort method sorts in-place and only for lists
# - sortred is a function and always returns a new list
# - sorted function can accept any object.

 

Sorting lists by word length

 

http://www.daniweb.com/software-development/python/threads/54348/sorting-lists-by-word-length-how-do-i-do-it

 

words = sorted(words, key = lambda str: len(str))

 

# Invoking .Sort & Sorted

# Python provides two ways to sort a sequence,
# the dot sort method and the function sorted.

l1 = [1, 7, 4, -2 ,3]
l2 = ["cherry", "apple", "blueberry"]

# .sort를 사용하는 경우 원본을 변경함
# None을 리턴
# 리스트에만 적용 가능
l1.sort()
print(l1)

l2.sort()
print(l2)

# sorted 함수를 사용하는 경우 원본 리스트는 변경 없음
# 새로운 시퀀스를 리턴
# .sort와 달리 리스트 이외의 시퀀스에도 적용 가능
sorted_l1 = sorted(l1)
print(sorted_l1)

sorted_l2 = sorted(l2)
print(sorted_l2)

print(sorted("apple"))

# 결과
[-2, 1, 3, 4, 7]
['apple', 'blueberry', 'cherry']
[-2, 1, 3, 4, 7]
['apple', 'blueberry', 'cherry']
['a', 'e', 'l', 'p', 'p']

 

# Optional reverse parameter

fs = ["cherry", "apple", "blueberry"]
print(sorted(fs, reverse=True))

# 결과
['cherry', 'blueberry', 'apple']

 

# Optional key parameter
#
# So, to make sense of this,
# we need to have a little mental model,
# a way to think about what's going on inside the sorted function.
# We're passing it in this function and what is it doing
# with that function?
# What it's doing is before it starts comparing any of the items
# to each other, remember comparisons that's like the pair of
# dancers comparing their numbers to each other.
# So, before it does any of theose comparisons,
# the sorted function uses the function that you pass in
# absolute and it uses that to determine numbers to assign to
# each of those dancers.
# That is behind the scenes, when you call sorted,
# sorted is going to call the fuction that you provide and
# it's going to call it once for each of the items in the sequences.
# It's going to do that to determine some property of that item like
# its absolute value, it's going to write it down on a little post-it
# note that the item carries around.
# Then, the sorted function does all the comparisons between the items
# but the comparison is always between the values that are on those
# post-it notes.

ls = [1, 7, 4, -2, 3]

# 정렬을 위한 비교는 하는데 원본 값을 변형해서 비교한다.
def absolute(x):
    if x >= 0:
        return x
    else:
        return -x

sorted_ls = sorted(ls, key=absolute)
print(sorted_ls)

# or
# 키가 함수라는 걸 명확하게 하기 위해
sorted_ls2 = sorted(ls, key=lambda x: absolute(x))
print(sorted_ls2)

# 결과
[1, -2, 3, 4, 7]
[1, -2, 3, 4, 7]

 

# Sorting a Dictionary's Keys

L = ['E', 'F', 'B', 'A', 'D', 'I', 'I', 'C', 'B', 'A', 'D', 'D', 'E', 'D']

d = {}
for x in L:
    if x in d:
        d[x] = d[x] + 1
    else:
        d[x] = 1
# for x in d.keys():
    # print(f"{x} appears {d[x]} times.")

# 키로 정렬
for x in sorted(d.keys()):
    print(f"{x} appears {d[x]} times.")

print("")
# 값으로 정렬한다면?
# 주의할 점은 x와 k가 같으면 안 된다.
# k는 .keys()의 요소이고, x는 정렬된 값이다.
# k와 x가 같으면 잘못된 결과가 나온다.
for x in sorted(d.keys(), key=lambda k: d[k]):
    print(f"{x} appears {d[x]} times.")

# 결과
# 키로 정렬
A appears 2 times.
B appears 2 times.
C appears 1 times.
D appears 4 times.
E appears 2 times.
F appears 1 times.
I appears 2 times.

# 값으로 정렬
F appears 1 times.
C appears 1 times.
E appears 2 times.
B appears 2 times.
A appears 2 times.
I appears 2 times.
D appears 4 times.

 

# Breaking Ties: Second Sorting
# When you sort tuples,
# you're really sorting by the first element in those tuples.
# But there is more.
# We have a built-in tie-breaking mechanism, with tuples sorting.
#
# So, when it compares two tuples,
# it first compares their first elements.
# If one of them is smaller than that whole tuple is smaller,
# but if they're equal, it goes on to compare the second elements
# of the tuples, and then the third elements and so on.

tups = [('A', 3, 2),
        ('C', 1, 4),
        ('B', 3, 1),
        ('A', 2, 4),
        ('C', 1, 2)]
for tup in sorted(tups):
    print(tup)

# 결과
('A', 2, 4)
('A', 3, 2)
('B', 3, 1)
('C', 1, 2)
('C', 1, 4)

# tuple 정렬이 열을 기준으로 순차로 정렬을 하는 속성을 이용해서
# 길이가 짧으면서, 길이가 동일하면 이름으로 정렬하는 sorting 구현
fruits = ['peach', 'kiwi', 'apple', 'blueberry', 'papaya', 'mango', 'pear']
new_order = sorted(fruits, key=lambda fruit_name: (len(fruit_name), fruit_name))
for fruit in new_order:
    print(fruit)

# -->
# Look at the first element of the tuple first.
# However, when it comes along, and sees four comma pear, (4, "pear")
# it's going to have a tie, when it compares 4 with 4,
# and it's going to then use alphabetic ordering as the
# secondary sort order to break the ties.

# 결과
kiwi
pear
apple
mango
peach
papaya
blueberry

 

# When to use a Lambda Expression

states = {"Minnesota": ["St. Paul", "Minneapolis", "Saint Cloud", "Stillwater"],
          "Michigan": ["Ann Arbor", "Traverse City", "Lansing", "Kalamazoo"],
          "Washington": ["Seattle", "Tacoma", "Olympia", "Vancouver"]}

print(sorted(states, key=lambda state: len(states[state][0])))
print(f'states["Washington"][0] = {states["Washington"][0]}, {len(states["Washington"][0])}')
print(f'states["Minnesota"][0] = {states["Minnesota"][0]}, {len(states["Minnesota"][0])}')
print(f'states["Michigan"][0] = {states["Michigan"][0]}, {len(states["Michigan"][0])}')

# 결과 (첫 번째 도시 이름이 짧은 순으로 정렬)
['Washington', 'Minnesota', 'Michigan']
states["Washington"][0] = Seattle, 7
states["Minnesota"][0] = St. Paul, 8
states["Michigan"][0] = Ann Arbor, 9

 

# 그룹에 있는 요소의 가중치를 사용해 정렬
numbers = [8, 3, 1, 2, 5, 4, 7, 6]
group = [2, 3, 5, 7]

def helper(x):
    if x in group:
        return (0, x) # 먼저 첫 번째 요소로 정렬하고, 같으면 두 번째 요소로 정렬
    return (1, x) # 그룹에 있는 것이 (0, x) 이므로 이것은 뒤로 밀린다.

numbers.sort(key=helper)
print(numbers)

# 결과 (그룹 내에 있는 것을 먼저 정렬하고, 다시 원래 요소로 정렬한다.)
[2, 3, 5, 7, 1, 4, 6, 8]

 

# class를 만들어서 key 함수 호출에 이용
class Sorter():
    def __init__(self, group):
        self.group = group
        self.found = False
    def __call__(self, x):
        if x in self.group:
            self.found = True
            return (0, x)
        return (1, x)

numbers = [8, 3, 1, 2, 5, 4, 7, 6]
group = [2, 3, 5, 7]

sorter = Sorter(group)
numbers.sort(key=sorter)
print(sorter.found)
print(numbers)

# 결과
True
[2, 3, 5, 7, 1, 4, 6, 8]

 

# Sorter 예제가 인상적이어서 순전히 기억에 의존해 다시 작성해 보았다.

# 그룹에 있는 요소를 먼저 정렬하고 나머지 정렬하기
group = [7, 2, 1]
lst = [1, 4, 5, 2, 7, 9, 11, 34, 3]

# 방법 1 - 함수형
def sort_first(n):
    if n in group:
        return (0, n)
    else:
        return (1, n)

result = sorted(lst, key=sort_first)
print(result)

# 방법 2 - 클래스 이용 (상태값 반환 가능)

class SortPriority():
    def __init__(self, group):
        self.group = group
        self.found = False
    def __call__(self, n):
        self.n = n
        if self.n in self.group:
            self.found = True
            return (0, n)
        else:
            return (1, n)

sp = SortPriority(group)
result_sort_priority = sorted(lst, key=sp)
print(sp.found)
print(result_sort_priority)

# 결과
[1, 2, 7, 3, 4, 5, 9, 11, 34]
True
[1, 2, 7, 3, 4, 5, 9, 11, 34]
반응형

관련글 더보기

댓글 영역