[python] पायथन में "नामित tuples" क्या हैं?



Answers

namedtuple एक टुपल वर्ग बनाने के लिए एक कारखाना समारोह है । उस वर्ग के साथ हम उन tuples बना सकते हैं जो नाम से भी कॉल करने योग्य हैं।

import collections

#Create a namedtuple class with names "a" "b" "c"
Row = collections.namedtuple("Row", ["a", "b", "c"], verbose=False, rename=False)   

row = Row(a=1,b=2,c=3) #Make a namedtuple from the Row class we created

print row    #Prints: Row(a=1, b=2, c=3)
print row.a  #Prints: 1
print row[0] #Prints: 1

row = Row._make([2, 3, 4]) #Make a namedtuple from a list of values

print row   #Prints: Row(a=2, b=3, c=4)
Question

पायथन 3.1 में परिवर्तनों को पढ़ना, मुझे कुछ मिला ... अप्रत्याशित:

Sys.version_info tuple अब नामित टुपल है:

मैंने पहले नामित tuples के बारे में कभी नहीं सुना, और मैंने सोचा कि तत्वों को या तो संख्याओं (जैसे tuples और सूचियों में) या कुंजी (जैसे dicts) द्वारा अनुक्रमित किया जा सकता है। मैंने कभी उम्मीद नहीं की कि उन्हें दोनों तरीकों से अनुक्रमित किया जा सकता है।

इस प्रकार, मेरे प्रश्न हैं:

  • Tuples नाम क्या हैं?
  • उनका उपयोग कैसे करें?
  • मुझे सामान्य tuples के बजाय नामित tuples का उपयोग क्यों / कब करना चाहिए?
  • नामित tuples के बजाय मैं सामान्य tuples का उपयोग क्यों / कब करना चाहिए?
  • क्या किसी भी तरह की "नामित सूची" (नामित टुपल का एक परिवर्तनीय संस्करण) है?



हर किसी ने पहले से ही इसका उत्तर दिया है, लेकिन मुझे लगता है कि मेरे पास अभी भी कुछ और जोड़ने के लिए है।

Namedtuple को कक्षा को परिभाषित करने के लिए एक शॉर्टकट के रूप में सहजता से समझा जा सकता है।

class को परिभाषित करने के लिए एक बोझिल और पारंपरिक तरीका देखें।

class Duck:
    def __init__(self, color, weight):
        self.color = color
        self.weight = weight
red_duck = Duck('red', '10')

    In [50]: red_duck
    Out[50]: <__main__.Duck at 0x1068e4e10>
    In [51]: red_duck.color
    Out[51]: 'red'

नाम के लिए के रूप में

from collections import namedtuple
Duck = namedtuple('Duck', ['color', 'weight'])
red_duck = Duck('red', '10')

In [54]: red_duck
Out[54]: Duck(color='red', weight='10')
In [55]: red_duck.color
Out[55]: 'red'



namedtuple

अपने कोड को साफ करने और इसे और अधिक पठनीय बनाने के सबसे आसान तरीकों में से एक है। यह tuple में क्या हो रहा है स्वयं दस्तावेज। Namedtuples उदाहरण नियमित रूप से स्मृति के रूप में स्मृति कुशल हैं क्योंकि उनके पास प्रति-उदाहरण शब्दकोश नहीं हैं, जो उन्हें शब्दकोशों से तेज़ी से बनाते हैं।

from collections import namedtuple

Color = namedtuple('Color', ['hue', 'saturation', 'luminosity'])

 p = Color(170, 0.1, 0.6)
 if p.saturation >= 0.5:
     print "Whew, that is bright!"
 if p.luminosity >= 0.5:
     print "Wow, that is light"

ट्यूपल में प्रत्येक तत्व का नामकरण किए बिना, यह इस तरह पढ़ा जाएगा:

p = (170, 0.1, 0.6)
if p[1] >= 0.5:
    print "Whew, that is bright!"
if p[2]>= 0.5:
   print "Wow, that is light"

यह समझना बहुत कठिन है कि पहले उदाहरण में क्या हो रहा है। एक नाम के साथ, प्रत्येक क्षेत्र का नाम होता है। और आप इसे स्थिति या अनुक्रमणिका के बजाय नाम से एक्सेस करते हैं। p[1] बजाय, हम इसे p.saturation कह सकते हैं। समझना आसान है। और यह क्लीनर दिखता है।

नामांकित करने का एक उदाहरण बनाना एक शब्दकोश बनाने से आसान है।

# dictionary
>>>p = dict(hue = 170, saturation = 0.1, luminosity = 0.6)
>>>p['hue']
170

#nametuple
>>>from collections import namedtuple
>>>Color = namedtuple('Color', ['hue', 'saturation', 'luminosity'])
>>>p = Color(170, 0.1, 0.6)
>>>p.hue
170

आप नामांकित का उपयोग कब कर सकते हैं

  1. जैसा कि अभी कहा गया है, नामित समझने से ट्यूल्स को अधिक आसान बना दिया जाता है। इसलिए यदि आपको टुपल में आइटमों का संदर्भ देने की आवश्यकता है, तो उन्हें नामांकित के रूप में बनाना केवल समझ में आता है।
  2. एक शब्दकोश से अधिक हल्के होने के अलावा, नामांकित भी शब्दकोश के विपरीत आदेश रखता है।
  3. उपर्युक्त उदाहरण में, शब्दकोश की तुलना में नामित अप्प्लू का उदाहरण बनाना आसान है। और नामित टुपल में आइटम का संदर्भ एक शब्दकोश से क्लीनर दिखता है। p['hue'] बजाय p.hue

वाक्यविन्यास

collections.namedtuple(typename, field_names[, verbose=False][, rename=False])
  • नाम पुस्तकालय संग्रह पुस्तकालय में है।
  • टाइपनाम: यह नए ट्यूपल सबक्लास का नाम है।
  • field_names: प्रत्येक फ़ील्ड के लिए नामों का अनुक्रम। यह एक सूची ['x', 'y', 'z'] या स्ट्रिंग xyz (कॉमा के बिना, केवल सफेद जगह) या x, y, z में अनुक्रम हो सकता है।
  • नाम बदलें: यदि नाम True , तो अवैध फ़ील्ड नाम स्वचालित रूप से स्थितिगत नामों से प्रतिस्थापित हो जाते हैं। उदाहरण के लिए, ['abc', 'def', 'ghi','abc'] को ['abc', '_1', 'ghi', '_3'] , कीवर्ड 'def' समाप्त कर रहा है (तब से कार्यों को परिभाषित करने के लिए एक आरक्षित शब्द है) और डुप्लिकेट फ़ील्डनाम 'abc'
  • verbose: यदि verbose True , वर्ग परिभाषा बस बनाया जाने से पहले मुद्रित है।

यदि आप चुनते हैं तो आप अभी भी उनकी स्थिति से नामांकितों तक पहुंच सकते हैं। p[1] == p.saturationp[1] == p.saturation । यह अभी भी एक नियमित tuple की तरह unpacks।

तरीके

सभी नियमित ट्यूपल विधियों का समर्थन किया जाता है। पूर्व: न्यूनतम (), अधिकतम (), लेन (), में, नहीं, concatenation (+), सूचकांक, टुकड़ा, आदि में और नाम के लिए कुछ अतिरिक्त हैं। नोट: ये सभी अंडरस्कोर से शुरू होते हैं। _replace , _make , _asdict

_replace निर्दिष्ट फ़ील्ड को नए मानों के साथ नामित _replace एक नया उदाहरण देता है।

वाक्यविन्यास

somenamedtuple._replace(kwargs)

उदाहरण

>>>from collections import namedtuple

>>>Color = namedtuple('Color', ['hue', 'saturation', 'luminosity'])
>>>p = Color(170, 0.1, 0.6)

>>>p._replace(hue=87)
Color(87, 0.1, 0.6)

>>>p._replace(hue=87, saturation=0.2)
Color(87, 0.2, 0.6)

नोटिस : फ़ील्ड नाम उद्धरण में नहीं हैं; वे यहाँ कीवर्ड हैं। याद रखें : टुपल्स अपरिवर्तनीय हैं - भले ही वे _replace हैं और _replace विधि है। _replace एक new उदाहरण पैदा करता है; यह मूल को संशोधित नहीं करता है या पुराने मान को प्रतिस्थापित नहीं करता है। आप निश्चित रूप से चर के लिए नया परिणाम बचा सकते हैं। p = p._replace(hue=169)

_make

मौजूदा अनुक्रम या पुनरावर्तनीय से एक नया उदाहरण बनाता है।

वाक्यविन्यास

somenamedtuple._make(iterable)

उदाहरण

 >>>data = (170, 0.1, 0.6)
 >>>Color._make(data)
Color(hue=170, saturation=0.1, luminosity=0.6)

>>>Color._make([170, 0.1, 0.6])  #the list is an iterable
Color(hue=170, saturation=0.1, luminosity=0.6)

>>>Color._make((170, 0.1, 0.6))  #the tuple is an iterable
Color(hue=170, saturation=0.1, luminosity=0.6)

>>>Color._make(170, 0.1, 0.6) 
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<string>", line 15, in _make
TypeError: 'float' object is not callable

आखिरी के साथ क्या हुआ? कोष्ठक के अंदर की वस्तु को पुनरावर्तनीय होना चाहिए। इसलिए कोष्ठक के अंदर एक सूची या टुपल काम करता है, लेकिन एक पुनरावर्तनीय के रूप में संलग्न किए बिना मूल्यों का अनुक्रम एक त्रुटि देता है।

_asdict

एक नया OrderedDict देता है जो फील्ड नामों को उनके संबंधित मानों पर मानचित्र करता है।

वाक्यविन्यास

somenamedtuple._asdict()

उदाहरण

 >>>p._asdict()
OrderedDict([('hue', 169), ('saturation', 0.1), ('luminosity', 0.6)])

संदर्भ : https://www.reddit.com/r/Python/comments/38ee9d/intro_to_namedtuple/

नामित सूची भी है जो नामित tuple के समान है लेकिन mutable https://pypi.python.org/pypi/namedlist




Tuples नाम क्या हैं?

एक नामित ट्यूपल एक ट्यूपल है।

यह सब कुछ एक tuple कर सकते हैं।

लेकिन यह सिर्फ एक tuple से अधिक है।

यह एक टुपल का एक विशिष्ट उप-वर्ग है जो आपके विनिर्देशों के लिए प्रोग्रामेटिक रूप से बनाया गया है, नामित फ़ील्ड और निश्चित लंबाई के साथ।

यह, उदाहरण के लिए, ट्यूपल का उप-वर्ग बनाता है, और निश्चित लंबाई (इस मामले में, तीन) होने के अलावा, इसे हर जगह इस्तेमाल किया जा सकता है बिना किसी टपले का उपयोग किया जाता है। इसे लिस्कोव प्रतिस्थापन के रूप में जाना जाता है:

>>> from collections import namedtuple
>>> class_name = 'ANamedTuple'
>>> fields = 'foo bar baz'
>>> ANamedTuple = namedtuple(class_name, fields)

यह इसे तुरंत चालू करता है:

>>> ant = ANamedTuple(1, 'bar', [])

हम इसका निरीक्षण कर सकते हैं और इसके गुणों का उपयोग कर सकते हैं:

>>> ant
ANamedTuple(foo=1, bar='bar', baz=[])
>>> ant.foo
1
>>> ant.bar
'bar'
>>> ant.baz.append('anything')
>>> ant.baz
['anything']

गहरी व्याख्या

नामित tuples को समझने के लिए, आपको सबसे पहले पता होना चाहिए कि एक ट्यूपल क्या है। एक ट्यूपल अनिवार्य रूप से एक अपरिवर्तनीय (स्मृति में जगह में बदला नहीं जा सकता) सूची है।

यहां बताया गया है कि आप नियमित ट्यूपल का उपयोग कैसे कर सकते हैं:

>>> student_tuple = 'Lisa', 'Simpson', 'A'
>>> student_tuple
('Lisa', 'Simpson', 'A')
>>> student_tuple[0]
'Lisa'
>>> student_tuple[1]
'Simpson'
>>> student_tuple[2]
'A'

आप टिकाऊ अनपॅकिंग के साथ एक टुपल का विस्तार कर सकते हैं:

>>> first, last, grade = student_tuple
>>> first
'Lisa'
>>> last
'Simpson'
>>> grade
'A'

नामांकित tuples tuples हैं जो उनके तत्वों को सिर्फ सूचकांक के बजाय नाम से उपयोग करने की अनुमति देता है!

आप इस तरह एक नामांकित बनाते हैं:

>>> from collections import namedtuple
>>> Student = namedtuple('Student', ['first', 'last', 'grade'])

आप रिक्त स्थान से अलग नामों के साथ एक स्ट्रिंग का भी उपयोग कर सकते हैं, एपीआई का थोड़ा और अधिक उपयोग करने योग्य उपयोग:

>>> Student = namedtuple('Student', 'first last grade')

उनका उपयोग कैसे करें?

आप सब कुछ कर सकते हैं tuples कर सकते हैं (ऊपर देखें) साथ ही साथ निम्न कार्य करें:

>>> named_student_tuple = Student('Lisa', 'Simpson', 'A')
>>> named_student_tuple.first
'Lisa'
>>> named_student_tuple.last
'Simpson'
>>> named_student_tuple.grade
'A'
>>> named_student_tuple._asdict()
OrderedDict([('first', 'Lisa'), ('last', 'Simpson'), ('grade', 'A')])
>>> vars(named_student_tuple)
OrderedDict([('first', 'Lisa'), ('last', 'Simpson'), ('grade', 'A')])
>>> new_named_student_tuple = named_student_tuple._replace(first='Bart', grade='C')
>>> new_named_student_tuple
Student(first='Bart', last='Simpson', grade='C')

मुझे सामान्य tuples के बजाय नामित tuples का उपयोग क्यों / कब करना चाहिए?

जब आप अपने कोड में व्यक्त tuple तत्वों के अर्थशास्त्र के लिए अपने कोड में सुधार होता है तो उनका उपयोग करें। यदि आप अन्यथा किसी ऑब्जेक्ट को अपरिवर्तनीय डेटा विशेषताओं और कोई कार्यक्षमता के साथ उपयोग नहीं करते हैं तो आप किसी ऑब्जेक्ट के बजाय उनका उपयोग कर सकते हैं। आप कार्यक्षमता जोड़ने के लिए उन्हें उपclass भी कर सकते हैं , उदाहरण के लिए :

class Point(namedtuple('Point', 'x y')):
    """adding functionality to a named tuple"""
        __slots__ = ()
        @property
        def hypot(self):
            return (self.x ** 2 + self.y ** 2) ** 0.5
        def __str__(self):
            return 'Point: x=%6.3f  y=%6.3f  hypot=%6.3f' % (self.x, self.y, self.hypot)

नामित tuples के बजाय मैं सामान्य tuples का उपयोग क्यों / कब करना चाहिए?

यह नामित tuples tuples के उपयोग से स्विच करने के लिए शायद एक रिग्रेशन होगा। अपफ्रंट डिज़ाइन निर्णय इस बात के आसपास केंद्रित है कि इसमें शामिल अतिरिक्त कोड से लागत ट्यूपल का उपयोग होने पर बेहतर पठनीयता के लायक है या नहीं।

नामित tuples बनाम tuples द्वारा उपयोग की जाने वाली कोई अतिरिक्त स्मृति नहीं है।

क्या किसी भी तरह की "नामित सूची" (नामित टुपल का एक परिवर्तनीय संस्करण) है?

आप या तो एक स्लॉट ऑब्जेक्ट की तलाश में हैं जो एक स्थिर आकार की सूची या उप-वर्गीकृत सूची की सभी कार्यक्षमताओं को लागू करता है जो नामित टुपल की तरह काम करता है (और किसी भी तरह से सूची को आकार में बदलने से रोकता है।)

अब विस्तारित, और शायद यहां तक ​​कि Liskov substitutable, पहले का उदाहरण:

from collections import Sequence

class MutableTuple(Sequence): 
    """Abstract Base Class for objects that work like mutable
    namedtuples. Subclass and define your named fields with 
    __slots__ and away you go.
    """
    __slots__ = ()
    def __init__(self, *args):
        for slot, arg in zip(self.__slots__, args):
            setattr(self, slot, arg)
    def __repr__(self):
        return type(self).__name__ + repr(tuple(self))
    # more direct __iter__ than Sequence's
    def __iter__(self): 
        for name in self.__slots__:
            yield getattr(self, name)
    # Sequence requires __getitem__ & __len__:
    def __getitem__(self, index):
        return getattr(self, self.__slots__[index])
    def __len__(self):
        return len(self.__slots__)

और उपयोग करने के लिए, बस subclass और __slots__ परिभाषित __slots__ :

class Student(MutableTuple):
    __slots__ = 'first', 'last', 'grade' # customize 


>>> student = Student('Lisa', 'Simpson', 'A')
>>> student
Student('Lisa', 'Simpson', 'A')
>>> first, last, grade = student
>>> first
'Lisa'
>>> last
'Simpson'
>>> grade
'A'
>>> student[0]
'Lisa'
>>> student[2]
'A'
>>> len(student)
3
>>> 'Lisa' in student
True
>>> 'Bart' in student
False
>>> student.first = 'Bart'
>>> for i in student: print(i)
... 
Bart
Simpson
A



पाइथन में अंदर नामित टुपल नामक कंटेनर का अच्छा उपयोग होता है, इसका उपयोग कक्षा की परिभाषा बनाने के लिए किया जा सकता है और इसमें मूल ट्यूपल की सभी सुविधाएं हैं।

नामित टुपल का उपयोग सीधे एक साधारण वर्ग उत्पन्न करने के लिए डिफ़ॉल्ट वर्ग टेम्पलेट पर लागू किया जाएगा, यह विधि बहुत से कोड को पठनीयता में सुधार करने की अनुमति देती है और कक्षा को परिभाषित करते समय भी यह बहुत सुविधाजनक है।




Links