수색…


여러 값의 최소값 또는 최대 값 얻기

min(7,2,1,5)
# Output: 1

max(7,2,1,5)
# Output: 7

키 인수 사용

시퀀스 시퀀스의 최소 / 최대를 찾는 것이 가능합니다 :

list_of_tuples = [(0, 10), (1, 15), (2, 8)]
min(list_of_tuples)
# Output: (0, 10)

그러나 각 시퀀스의 특정 요소를 기준으로 정렬하려면 key argument를 사용하십시오.

min(list_of_tuples, key=lambda x: x[0])         # Sorting by first element
# Output: (0, 10)

min(list_of_tuples, key=lambda x: x[1])         # Sorting by second element
# Output: (2, 8)

sorted(list_of_tuples, key=lambda x: x[0])      # Sorting by first element (increasing)
# Output: [(0, 10), (1, 15), (2, 8)]

sorted(list_of_tuples, key=lambda x: x[1])      # Sorting by first element
# Output: [(2, 8), (0, 10), (1, 15)]

import operator   
# The operator module contains efficient alternatives to the lambda function
max(list_of_tuples, key=operator.itemgetter(0)) # Sorting by first element
# Output: (2, 8)

max(list_of_tuples, key=operator.itemgetter(1)) # Sorting by second element
# Output: (1, 15)

sorted(list_of_tuples, key=operator.itemgetter(0), reverse=True) # Reversed (decreasing)
# Output: [(2, 8), (1, 15), (0, 10)]

sorted(list_of_tuples, key=operator.itemgetter(1), reverse=True) # Reversed(decreasing)
# Output: [(1, 15), (0, 10), (2, 8)]

기본 인수는 max, min입니다.

빈 시퀀스를 max 또는 min 로 전달할 수 없습니다.

min([])

ValueError : min () arg는 빈 시퀀스입니다.

그러나 Python 3에서는 예외를 발생시키는 대신 시퀀스가 ​​비어있는 경우 반환 될 값 default 키워드 인수 default 를 전달할 수 있습니다.

max([], default=42)        
# Output: 42
max([], default=0)        
# Output: 0

특별한 경우 : 사전

최소값 또는 최대 값을 sorted 거나 sorted 사용하는 것은 객체에 대한 반복에 따라 다릅니다. dict 의 경우 반복은 키에만 적용됩니다.

adict = {'a': 3, 'b': 5, 'c': 1}
min(adict)
# Output: 'a'
max(adict)
# Output: 'c'
sorted(adict)
# Output: ['a', 'b', 'c']

사전 구조를 유지하려면 .items() 를 반복해야합니다.

min(adict.items())
# Output: ('a', 3)
max(adict.items())
# Output: ('c', 1)
sorted(adict.items())
# Output: [('a', 3), ('b', 5), ('c', 1)]

sorted , dict 와 같은 구조를 유지하면서 정렬을 유지하는 OrderedDict 를 만들 수 있습니다.

from collections import OrderedDict
OrderedDict(sorted(adict.items()))
# Output: OrderedDict([('a', 3), ('b', 5), ('c', 1)])
res = OrderedDict(sorted(adict.items()))
res['a']
# Output: 3

가치에 의해

다시 이것은 key 인수를 사용하여 가능합니다.

min(adict.items(), key=lambda x: x[1])
# Output: ('c', 1)
max(adict.items(), key=operator.itemgetter(1))
# Output: ('b', 5)
sorted(adict.items(), key=operator.itemgetter(1), reverse=True)
# Output: [('b', 5), ('a', 3), ('c', 1)]

정렬 된 시퀀스 가져 오기

하나의 시퀀스 사용 :

sorted((7, 2, 1, 5))                 # tuple
# Output: [1, 2, 5, 7]

sorted(['c', 'A', 'b'])              # list
# Output: ['A', 'b', 'c']

sorted({11, 8, 1})                   # set
# Output: [1, 8, 11]

sorted({'11': 5, '3': 2, '10': 15})  # dict
# Output: ['10', '11', '3']          # only iterates over the keys

sorted('bdca')                       # string
# Output: ['a','b','c','d']

결과는 항상 새로운 list . 원래 데이터는 변경되지 않습니다.

시퀀스의 최소 및 최대

최소 시퀀스 (iterable)를 얻는 것은 sorted 시퀀스의 첫 번째 요소를 액세스하는 것과 같습니다.

min([2, 7, 5])
# Output: 2
sorted([2, 7, 5])[0]
# Output: 2

sorted 순서를 유지하고 max 는 처음 만난 값을 반환하기 때문에 최대 값은 좀 더 복잡합니다. 중복이없는 경우 최대 값은 정렬 된 리턴의 마지막 요소와 동일합니다.

max([2, 7, 5])
# Output: 7
sorted([2, 7, 5])[-1]
# Output: 7

그러나 최대 값을 갖는 것으로 평가되는 요소가 여러 개있는 경우는 예외입니다.

class MyClass(object):
    def __init__(self, value, name):
        self.value = value
        self.name = name
        
    def __lt__(self, other):
        return self.value < other.value
    
    def __repr__(self):
        return str(self.name)

sorted([MyClass(4, 'first'), MyClass(1, 'second'), MyClass(4, 'third')])
# Output: [second, first, third]
max([MyClass(4, 'first'), MyClass(1, 'second'), MyClass(4, 'third')])
# Output: first

< 또는 > 조작을 지원하는 요소를 포함하는 반복 가능한 모든 허용됩니다.

맞춤 클래스를 주문형으로 만들기

min , maxsorted 모두 객체가 순서 가능해야합니다. 제대로 주문할 수 있으려면 __lt__ , __gt__ , __ge__ , __le__ , __ne____eq__ 의 6 가지 방법을 모두 정의해야합니다.

class IntegerContainer(object):
    def __init__(self, value):
        self.value = value
        
    def __repr__(self):
        return "{}({})".format(self.__class__.__name__, self.value)
    
    def __lt__(self, other):
        print('{!r} - Test less than {!r}'.format(self, other))
        return self.value < other.value
    
    def __le__(self, other):
        print('{!r} - Test less than or equal to {!r}'.format(self, other))
        return self.value <= other.value

    def __gt__(self, other):
        print('{!r} - Test greater than {!r}'.format(self, other))
        return self.value > other.value

    def __ge__(self, other):
        print('{!r} - Test greater than or equal to {!r}'.format(self, other))
        return self.value >= other.value

    def __eq__(self, other):
        print('{!r} - Test equal to {!r}'.format(self, other))
        return self.value == other.value

    def __ne__(self, other):
        print('{!r} - Test not equal to {!r}'.format(self, other))
        return self.value != other.value

이 모든 메소드를 구현하는 것은 불필요한 것처럼 보일 지 모르지만 일부 코드를 생략하면 코드에 버그가 발생하기 쉽습니다 .

예 :

alist = [IntegerContainer(5), IntegerContainer(3),
         IntegerContainer(10), IntegerContainer(7)
        ]

res = max(alist)
# Out: IntegerContainer(3) - Test greater than IntegerContainer(5)
#      IntegerContainer(10) - Test greater than IntegerContainer(5)
#      IntegerContainer(7) - Test greater than IntegerContainer(10)
print(res)
# Out: IntegerContainer(10)

res = min(alist)   
# Out: IntegerContainer(3) - Test less than IntegerContainer(5)
#      IntegerContainer(10) - Test less than IntegerContainer(3)
#      IntegerContainer(7) - Test less than IntegerContainer(3)
print(res)
# Out: IntegerContainer(3)

res = sorted(alist)
# Out: IntegerContainer(3) - Test less than IntegerContainer(5)
#      IntegerContainer(10) - Test less than IntegerContainer(3)
#      IntegerContainer(10) - Test less than IntegerContainer(5)
#      IntegerContainer(7) - Test less than IntegerContainer(5)
#      IntegerContainer(7) - Test less than IntegerContainer(10)
print(res)
# Out: [IntegerContainer(3), IntegerContainer(5), IntegerContainer(7), IntegerContainer(10)]

reverse=True sorted 또한 __lt__ 을 사용 __lt__ :

res = sorted(alist, reverse=True)
# Out: IntegerContainer(10) - Test less than IntegerContainer(7)
#      IntegerContainer(3) - Test less than IntegerContainer(10)
#      IntegerContainer(3) - Test less than IntegerContainer(10)
#      IntegerContainer(3) - Test less than IntegerContainer(7)
#      IntegerContainer(5) - Test less than IntegerContainer(7)
#      IntegerContainer(5) - Test less than IntegerContainer(3)
print(res)
# Out: [IntegerContainer(10), IntegerContainer(7), IntegerContainer(5), IntegerContainer(3)]

그러나 sorted 는 기본값이 구현되지 않은 경우 대신 __gt__ 을 사용할 수 있습니다.

del IntegerContainer.__lt__   # The IntegerContainer no longer implements "less than"

res = min(alist) 
# Out: IntegerContainer(5) - Test greater than IntegerContainer(3)
#      IntegerContainer(3) - Test greater than IntegerContainer(10)
#      IntegerContainer(3) - Test greater than IntegerContainer(7)
print(res)
# Out: IntegerContainer(3)

__lt____gt__ 도 구현되어 있지 않으면 메서드를 정렬하면 TypeError 가 발생합니다.

del IntegerContainer.__gt__   # The IntegerContainer no longer implements "greater then"

res = min(alist) 

TypeError : 순서가 잘못된 형식 : IntegerContainer () <IntegerContainer ()


functools.total_ordering 데코레이터는 이러한 다양한 비교 방법을 작성하는 작업을 단순화하는 데 사용할 수 있습니다. total_ordering 클래스를 total_ordering , __eq__ , __ne____lt__ , __le__ , __ge__ 또는 __gt__ 중 하나만 구현하면 __lt__ . __le__ 데코레이터가 나머지를 채울 것입니다.

import functools

@functools.total_ordering
class IntegerContainer(object):
    def __init__(self, value):
        self.value = value
        
    def __repr__(self):
        return "{}({})".format(self.__class__.__name__, self.value)
    
    def __lt__(self, other):
        print('{!r} - Test less than {!r}'.format(self, other))
        return self.value < other.value
    
    def __eq__(self, other):
        print('{!r} - Test equal to {!r}'.format(self, other))
        return self.value == other.value
    
    def __ne__(self, other):
        print('{!r} - Test not equal to {!r}'.format(self, other))
        return self.value != other.value


IntegerContainer(5) > IntegerContainer(6)
# Output: IntegerContainer(5) - Test less than IntegerContainer(6)
# Returns: False

IntegerContainer(6) > IntegerContainer(5)
# Output: IntegerContainer(6) - Test less than IntegerContainer(5)
# Output: IntegerContainer(6) - Test equal to IntegerContainer(5)
# Returns True

> ( 보다 큼 )이 이제는 보다 작음 메소드를 호출하고 어떤 경우에는 __eq__ 메소드를 호출하는 방법에 주목하십시오. 이것은 속도가 매우 중요하다면, 각각의 풍부한 비교 방법을 직접 구현해야한다는 것을 의미합니다.

iterable에서 N 개의 가장 큰 항목 또는 N 개의 가장 작은 항목 추출

iterable의 최대 값 또는 최소값의 숫자를 찾으려면 heapq 모듈의 nlargestnsmallest 를 사용할 수 있습니다.

import heapq

# get 5 largest items from the range

heapq.nlargest(5, range(10))
# Output: [9, 8, 7, 6, 5]

heapq.nsmallest(5, range(10))
# Output: [0, 1, 2, 3, 4]

이것은 전체 iterable을 정렬 한 다음 끝에 또는 처음부터 슬라이스하는 것보다 훨씬 효율적입니다. 내부적으로이 함수는 바이너리 힙 우선 순위 큐 데이터 구조를 사용하는데, 이는이 사용 사례에 매우 효율적입니다.

min , maxsorted 와 마찬가지로이 함수는 선택적 key 키워드 인수를 허용합니다.이 인수는 요소가 주어진 경우 정렬 키를 반환하는 함수 여야합니다.

다음은 파일에서 가장 긴 1000 줄을 추출하는 프로그램입니다 :

import heapq
with open(filename) as f:
    longest_lines = heapq.nlargest(1000, f, key=len)

여기에서 우리는 파일을 열고 파일 핸들 통과 f 하는 nlargest . 파일을 반복하면 파일의 각 행이 별도의 문자열로 생성됩니다. nlargest 다음 nlargest 가 각 요소 (또는 선)를 전달하여 len 함수로 전달하여 정렬 키를 결정합니다. len 은 문자열을 받으면 줄의 길이를 문자로 반환합니다.

지금까지 1000 개의 가장 큰 줄 목록에 대한 저장소 만 필요합니다.

longest_lines = sorted(f, key=len)[1000:]

전체 파일을 메모리 에 보유해야합니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow