Python Language
छँटाई, न्यूनतम और अधिकतम
खोज…
न्यूनतम या अधिकतम कई मान प्राप्त करना
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
उपयोग करें:
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
में खाली क्रम नहीं दे सकते:
min([])
ValueError: min () arg एक खाली क्रम है
हालाँकि, पायथन 3 के साथ, आप कीवर्ड तर्क में एक मान के साथ default
पास कर सकते हैं जो कि अपवाद खाली करने के बजाय यदि अनुक्रम खाली है, तो वापस कर दिया जाएगा:
max([], default=42)
# Output: 42
max([], default=0)
# Output: 0
विशेष मामला: शब्दकोशों
न्यूनतम या अधिकतम या sorted
का उपयोग करना ऑब्जेक्ट पर पुनरावृत्तियों पर निर्भर करता है। dict
के मामले में, पुनरावृत्ति केवल कुंजियों पर है:
adict = {'a': 3, 'b': 5, 'c': 1}
min(adict)
# Output: 'a'
max(adict)
# Output: 'c'
sorted(adict)
# Output: ['a', 'b', 'c']
शब्दकोश संरचना रखने के लिए, आपको .items()
पर .items()
:
min(adict.items())
# Output: ('a', 3)
max(adict.items())
# Output: ('c', 1)
sorted(adict.items())
# Output: [('a', 3), ('b', 5), ('c', 1)]
के लिए sorted
, आप एक बना सकते हैं OrderedDict
छंटाई एक करते हुए रखने के लिए dict
संरचना की तरह:
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
; मूल डेटा अपरिवर्तित रहता है।
एक अनुक्रम के न्यूनतम और अधिकतम
एक अनुक्रम (चलने योग्य) का न्यूनतम प्राप्त करना 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
, max
और sorted
सभी वस्तुओं को क्रमबद्ध होने की आवश्यकता है। ठीक से क्रमबद्ध होने के लिए, कक्षा को सभी 6 विधियों __lt__
, __gt__
, __ge__
, __le__
, __ne__
और __eq__
को परिभाषित करने की आवश्यकता है:
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
किया गया reverse=True
भी __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)
तरीकों छंटाई एक बढ़ा देंगे TypeError
है, तो न __lt__
है और न ही __gt__
कार्यान्वित कर रहे हैं:
del IntegerContainer.__gt__ # The IntegerContainer no longer implements "greater then"
res = min(alist)
TypeError: unorderable type: IntegerContainer () <IntegerContainer ()
functools.total_ordering
डेकोरेटर का उपयोग इन समृद्ध तुलना विधियों को लिखने के प्रयास को सरल बनाने में किया जा सकता है। यदि आप अपनी कक्षा को total_ordering
से total_ordering
, तो आपको __eq__
, __ne__
और केवल __lt__
, __le__
, __ge__
या __gt__
एक को लागू करने की आवश्यकता है, और डेकोरेटर बाकी में भर जाएगा:
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 की बढ़ते या घटते मूल्यों के कुछ संख्या (एक से अधिक) को खोजने के लिए, आप उपयोग कर सकते हैं nlargest
और nsmallest
की heapq
मॉड्यूल:
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]
यह पूरे चलने योग्य को छांटने और फिर अंत या शुरुआत से फिसलने की तुलना में बहुत अधिक कुशल है। आंतरिक रूप से ये फ़ंक्शन बाइनरी हीप प्राथमिकता कतार डेटा संरचना का उपयोग करते हैं, जो इस उपयोग के मामले के लिए बहुत कुशल है।
min
, max
और sorted
, ये फ़ंक्शन वैकल्पिक key
कीवर्ड तर्क को स्वीकार करते हैं, जो कि एक फ़ंक्शन होना चाहिए, जो एक तत्व दिया गया है, अपनी तरह की कुंजी देता है।
यहाँ एक प्रोग्राम है जो एक फाइल से 1000 सबसे लंबी लाइनों को निकालता है:
import heapq
with open(filename) as f:
longest_lines = heapq.nlargest(1000, f, key=len)
यहाँ हम फ़ाइल को खोलने, और फ़ाइल संभाल पारित f
को nlargest
। फ़ाइल को अलग करने से फ़ाइल की प्रत्येक पंक्ति एक अलग स्ट्रिंग के रूप में प्राप्त होती है; तब प्रत्येक तत्व (या लाइन) को nlargest
किया जाता है, जो उसकी क्रमबद्ध कुंजी को निर्धारित करने के लिए फ़ंक्शन len
जाता है। len
, एक स्ट्रिंग दिया, वर्णों में पंक्ति की लंबाई देता है।
इसके लिए केवल 1000 सबसे बड़ी लाइनों की सूची के लिए भंडारण की आवश्यकता होती है, जिसके साथ इसके विपरीत किया जा सकता है
longest_lines = sorted(f, key=len)[1000:]
जिसे मेमोरी में पूरी फाइल को होल्ड करना होगा।