Những gì được đặt tên là tuples tên trong Python là gì?


907

Đọc các thay đổi trong Python 3.1 , tôi thấy một điều ... không ngờ:

Bộ dữ liệu sys.version_info bây giờ là một bộ dữ liệu có tên :

Tôi chưa bao giờ nghe về các bộ dữ liệu được đặt tên trước đó và tôi nghĩ các yếu tố có thể được lập chỉ mục theo số (như trong bộ dữ liệu và danh sách) hoặc bằng các phím (như trong dicts). Tôi không bao giờ mong đợi họ có thể được lập chỉ mục cả hai cách.

Vì vậy, câu hỏi của tôi là:

  • Tuples được đặt tên là gì?
  • Làm thế nào để sử dụng chúng?
  • Tại sao / khi nào tôi nên sử dụng bộ dữ liệu có tên thay vì bộ dữ liệu thông thường?
  • Tại sao / khi nào tôi nên sử dụng bộ dữ liệu bình thường thay vì bộ dữ liệu được đặt tên?
  • Có bất kỳ loại "danh sách được đặt tên" (một phiên bản có thể thay đổi của bộ dữ liệu được đặt tên) không?

Câu trả lời:


1196

Các bộ dữ liệu được đặt tên về cơ bản là các loại đối tượng nhẹ, dễ tạo. Các trường hợp tuple được đặt tên có thể được tham chiếu bằng cách sử dụng hội nghị biến đổi giống như đối tượng hoặc cú pháp tuple tiêu chuẩn. Chúng có thể được sử dụng tương tự structhoặc các loại hồ sơ phổ biến khác, ngoại trừ việc chúng là bất biến. Chúng đã được thêm vào Python 2.6 và Python 3.0, mặc dù có một công thức để thực hiện trong Python 2.4 .

Ví dụ, thông thường đại diện cho một điểm là một tuple (x, y). Điều này dẫn đến mã như sau:

pt1 = (1.0, 5.0)
pt2 = (2.5, 1.5)

from math import sqrt
line_length = sqrt((pt1[0]-pt2[0])**2 + (pt1[1]-pt2[1])**2)

Sử dụng một tuple có tên nó trở nên dễ đọc hơn:

from collections import namedtuple
Point = namedtuple('Point', 'x y')
pt1 = Point(1.0, 5.0)
pt2 = Point(2.5, 1.5)

from math import sqrt
line_length = sqrt((pt1.x-pt2.x)**2 + (pt1.y-pt2.y)**2)

Tuy nhiên, các bộ dữ liệu được đặt tên vẫn tương thích ngược với các bộ dữ liệu thông thường, do đó, các bộ sau sẽ vẫn hoạt động:

Point = namedtuple('Point', 'x y')
pt1 = Point(1.0, 5.0)
pt2 = Point(2.5, 1.5)

from math import sqrt
# use index referencing
line_length = sqrt((pt1[0]-pt2[0])**2 + (pt1[1]-pt2[1])**2)
 # use tuple unpacking
x1, y1 = pt1

Vì vậy, bạn nên sử dụng các bộ dữ liệu được đặt tên thay vì bộ dữ liệu ở bất cứ nơi nào bạn nghĩ rằng ký hiệu đối tượng sẽ làm cho mã của bạn trở nên dễ thương hơn và dễ đọc hơn . Cá nhân tôi đã bắt đầu sử dụng chúng để biểu diễn các loại giá trị rất đơn giản, đặc biệt khi chuyển chúng dưới dạng tham số cho các hàm. Nó làm cho các chức năng dễ đọc hơn, mà không nhìn thấy bối cảnh của việc đóng gói tuple.

Hơn nữa, bạn cũng có thể thay thế các lớp bất biến thông thường không có chức năng , chỉ có các trường với chúng. Bạn thậm chí có thể sử dụng các loại tuple được đặt tên của mình làm các lớp cơ sở:

class Point(namedtuple('Point', 'x y')):
    [...]

Tuy nhiên, như với các bộ dữ liệu, các thuộc tính trong bộ dữ liệu được đặt tên là không thay đổi:

>>> Point = namedtuple('Point', 'x y')
>>> pt1 = Point(1.0, 5.0)
>>> pt1.x = 2.0
AttributeError: can't set attribute

Nếu bạn muốn có thể thay đổi các giá trị, bạn cần một loại khác. Có một công thức hữu ích cho các bản ghi có thể thay đổi cho phép bạn đặt các giá trị mới cho các thuộc tính.

>>> from rcdtype import *
>>> Point = recordtype('Point', 'x y')
>>> pt1 = Point(1.0, 5.0)
>>> pt1 = Point(1.0, 5.0)
>>> pt1.x = 2.0
>>> print(pt1[0])
    2.0

Tuy nhiên, tôi không biết bất kỳ hình thức "danh sách có tên" nào cho phép bạn thêm các trường mới. Bạn có thể chỉ muốn sử dụng một từ điển trong tình huống này. Các bộ dữ liệu được đặt tên có thể được chuyển đổi thành từ điển bằng cách sử dụng pt1._asdict()trả về {'x': 1.0, 'y': 5.0}và có thể được vận hành với tất cả các chức năng từ điển thông thường.

Như đã lưu ý, bạn nên kiểm tra tài liệu để biết thêm thông tin từ đó các ví dụ này được xây dựng.


35
từ python 3.7, cũng xem xét dataclasses như một sự thay thế (backport sẵn cho 3.6, nhưng các phiên bản trước đó không)
innov8

3
Trong trường hợp bạn cần loại bản ghi có thể thay đổi - sử dụng lớp đơn giản với định nghĩa__slots__
madzohan

lý do chính để sử dụng rcdtype không phải dataclass là gì
Voyager

Thay thế cho dict là từ điển stackoverflow.com/questions/4984647/
mrgloom

Vì đây là câu trả lời bạn luôn tìm thấy, có thể đáng nói là hiện tại cũng typing.NamedTuplecó cho phép gợi ý loại và đặc biệt thuận tiện cho việc phân lớp.
DerWeh

101

nametuple là một chức năng của nhà máy để tạo ra một lớp tuple. Với lớp đó, chúng ta có thể tạo các bộ dữ liệu có thể gọi theo tên.

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)

5
Các tham số verbose và đổi tên được mặc định thành Sai theo mặc định vì vậy chúng không cần phải được đặt thành giá trị này một cách rõ ràng.
Trismegistos

namedtuple is a factory function for making a tuple class.đó có lẽ là câu trả lời đúng duy nhất ở đây: P
Mr_and_Mrs_D

90

Tuples được đặt tên là gì?

Một tuple được đặt tên là một tuple.

Nó làm mọi thứ một tuple có thể.

Nhưng nó không chỉ là một tuple.

Đây là một lớp con cụ thể của một bộ dữ liệu được tạo lập trình theo đặc điểm kỹ thuật của bạn, với các trường được đặt tên và độ dài cố định.

Điều này, ví dụ, tạo ra một lớp con của bộ dữ liệu và ngoài việc có độ dài cố định (trong trường hợp này là ba), nó có thể được sử dụng ở mọi nơi mà một bộ dữ liệu được sử dụng mà không bị phá vỡ. Điều này được gọi là thay thế Liskov.

Mới trong Python 3.6 , chúng ta có thể sử dụng một định nghĩa lớptyping.NamedTupleđể tạo ra một tên được đặt tên:

from typing import NamedTuple

class ANamedTuple(NamedTuple):
    """a docstring"""
    foo: int
    bar: str
    baz: list

Ở trên giống như bên dưới, ngoại trừ bên trên có chú thích loại và một chuỗi doc. Dưới đây có sẵn trong Python 2+:

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

Điều này bắt đầu nó:

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

Chúng ta có thể kiểm tra nó và sử dụng các thuộc tính của nó:

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

Giải thích sâu hơn

Để hiểu các bộ dữ liệu được đặt tên, trước tiên bạn cần biết một bộ dữ liệu là gì. Một tuple về cơ bản là một danh sách bất biến (không thể thay đổi tại chỗ trong bộ nhớ).

Đây là cách bạn có thể sử dụng một tuple thông thường:

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

Bạn có thể mở rộng một tuple với giải nén lặp lại:

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

Các bộ dữ liệu được đặt tên là bộ dữ liệu cho phép các phần tử của chúng được truy cập theo tên thay vì chỉ mục lục!

Bạn tạo một cái tên như thế này:

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

Bạn cũng có thể sử dụng một chuỗi với các tên được phân tách bằng dấu cách, cách sử dụng API dễ đọc hơn một chút:

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

Làm thế nào để sử dụng chúng?

Bạn có thể làm mọi thứ mà bộ dữ liệu có thể làm (xem bên trên) cũng như làm như sau:

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

Một bình luận hỏi:

Trong một kịch bản hoặc chương trình lớn, người ta thường định nghĩa một bộ dữ liệu có tên ở đâu?

Các loại bạn tạo với namedtuple về cơ bản là các lớp bạn có thể tạo với tốc ký dễ dàng. Đối xử với họ như các lớp học. Xác định chúng ở cấp độ mô-đun, để dưa chua và những người dùng khác có thể tìm thấy chúng.

Ví dụ hoạt động, ở cấp độ mô-đun toàn cầu:

>>> from collections import namedtuple
>>> NT = namedtuple('NT', 'foo bar')
>>> nt = NT('foo', 'bar')
>>> import pickle
>>> pickle.loads(pickle.dumps(nt))
NT(foo='foo', bar='bar')

Và điều này chứng tỏ sự thất bại trong việc tra cứu định nghĩa:

>>> def foo():
...     LocalNT = namedtuple('LocalNT', 'foo bar')
...     return LocalNT('foo', 'bar')
... 
>>> pickle.loads(pickle.dumps(foo()))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
_pickle.PicklingError: Can't pickle <class '__main__.LocalNT'>: attribute lookup LocalNT on __main__ failed

Tại sao / khi nào tôi nên sử dụng bộ dữ liệu có tên thay vì bộ dữ liệu thông thường?

Sử dụng chúng khi nó cải thiện mã của bạn để có ngữ nghĩa của các phần tử tuple được thể hiện trong mã của bạn.

Bạn có thể sử dụng chúng thay vì một đối tượng nếu bạn thường sử dụng một đối tượng có thuộc tính dữ liệu không thay đổi và không có chức năng.

Bạn cũng có thể phân lớp chúng để thêm chức năng, ví dụ :

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)

Tại sao / khi nào tôi nên sử dụng bộ dữ liệu bình thường thay vì bộ dữ liệu được đặt tên?

Nó có thể là một hồi quy để chuyển từ sử dụng bộ dữ liệu được đặt tên sang bộ dữ liệu. Quyết định thiết kế trả trước xoay quanh việc liệu chi phí từ mã bổ sung có liên quan có xứng đáng với khả năng đọc được cải thiện khi sử dụng bộ dữ liệu hay không.

Không có bộ nhớ thêm được sử dụng bởi các bộ dữ liệu được đặt tên so với bộ dữ liệu.

Có bất kỳ loại "danh sách được đặt tên" (một phiên bản có thể thay đổi của bộ dữ liệu được đặt tên) không?

Bạn đang tìm kiếm một đối tượng có rãnh thực hiện tất cả các chức năng của danh sách có kích thước tĩnh hoặc danh sách được phân lớp hoạt động giống như một tuple có tên (và bằng cách nào đó chặn danh sách thay đổi kích thước.)

Một ví dụ bây giờ được mở rộng và thậm chí có thể thay thế Liskov, ví dụ đầu tiên:

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

Và để sử dụng, chỉ cần phân lớp và xác định __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

44

nametuples là một tính năng tuyệt vời, chúng là nơi chứa dữ liệu hoàn hảo. Khi bạn phải "lưu trữ" dữ liệu, bạn sẽ sử dụng bộ dữ liệu hoặc từ điển, như:

user = dict(name="John", age=20)

hoặc là:

user = ("John", 20)

Cách tiếp cận từ điển là áp đảo, vì dict là đột biến và chậm hơn so với tuples. Mặt khác, các bộ dữ liệu là bất biến và nhẹ nhưng thiếu khả năng đọc cho một số lượng lớn các mục trong các trường dữ liệu.

nametuples là sự thỏa hiệp hoàn hảo cho hai cách tiếp cận, có khả năng đọc, độ nhẹ và tính bất biến tuyệt vời (cộng với chúng là đa hình!).


9
Hãy nhớ rằng các tên được đặt chậm hơn so với dicts nếu bạn truy cập các thuộc tính của chúng theo tên: ntuple.foovs ntuple[1]cái sau nhanh hơn nhiều. Thông tin thêm về nó: stackoverflow.com/questions/2646157/
Mạnh

28

bộ dữ liệu có tên cho phép tương thích ngược với mã kiểm tra phiên bản như thế này

>>> sys.version_info[0:2]
(3, 1)

đồng thời cho phép mã tương lai rõ ràng hơn bằng cách sử dụng cú pháp này

>>> sys.version_info.major
3
>>> sys.version_info.minor
1

12

tên là

là một trong những cách dễ nhất để làm sạch mã của bạn và làm cho nó dễ đọc hơn. Nó tự ghi lại những gì đang xảy ra trong bộ dữ liệu. Các trường hợp được đặt tên chỉ có hiệu quả về bộ nhớ như các bộ dữ liệu thông thường vì chúng không có từ điển theo trường hợp, làm cho chúng nhanh hơn từ điển.

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"

Nếu không đặt tên cho từng thành phần trong bộ dữ liệu, nó sẽ đọc như sau:

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"

Thật khó để hiểu những gì đang diễn ra trong ví dụ đầu tiên. Với một tên được đặt tên, mỗi trường có một tên. Và bạn truy cập nó theo tên chứ không phải vị trí hoặc chỉ mục. Thay vì p[1], chúng ta có thể gọi nó là p.saturation. Nó dễ hiểu hơn. Và nó trông sạch sẽ hơn.

Tạo một thể hiện của nametuple dễ hơn tạo từ điển.

# 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

Khi nào bạn có thể sử dụng namtuple

  1. Như vừa nêu, têntuple làm cho việc hiểu các bộ dữ liệu dễ dàng hơn nhiều. Vì vậy, nếu bạn cần tham chiếu các mục trong bộ dữ liệu, thì việc tạo chúng dưới dạng tên là chỉ có ý nghĩa.
  2. Bên cạnh việc nhẹ hơn từ điển, nametuple cũng giữ trật tự không giống như từ điển.
  3. Như trong ví dụ trên, việc tạo một thể hiện của têntuple đơn giản hơn từ điển sẽ đơn giản hơn. Và tham khảo các mục trong tuple có tên trông sạch hơn một từ điển. p.huehơn p['hue'].

Cú pháp

collections.namedtuple(typename, field_names[, verbose=False][, rename=False])
  • nametuple có trong thư viện bộ sưu tập.
  • typename: Đây là tên của lớp con tuple mới.
  • field_names: Một chuỗi các tên cho mỗi trường. Nó có thể là một chuỗi như trong một danh sách ['x', 'y', 'z']hoặc chuỗi x y z(không có dấu phẩy, chỉ là khoảng trắng) hoặc x, y, z.
  • đổi tên: Nếu đổi tên là True, tên trường không hợp lệ sẽ tự động được thay thế bằng tên vị trí. Ví dụ: ['abc', 'def', 'ghi','abc']được chuyển đổi thành ['abc', '_1', 'ghi', '_3'], loại bỏ từ khóa 'def'(vì đó là một từ dành riêng để xác định hàm) và tên trường trùng lặp 'abc'.
  • verbose: Nếu verbose là True, định nghĩa lớp được in ngay trước khi được xây dựng.

Bạn vẫn có thể truy cập các tên được đặt theo vị trí của chúng, nếu bạn chọn. p[1] == p.saturation. Nó vẫn giải nén như một tuple thông thường.

Phương pháp

Tất cả các phương pháp tuple thông thường được hỗ trợ. Ví dụ: min (), max (), len (), in, not in, concatenation (+), index, lát, v.v. Và có một vài cái bổ sung cho têntuple. Lưu ý: tất cả đều bắt đầu bằng dấu gạch dưới. _replace, _make, _asdict.

_replace Trả về một thể hiện mới của bộ dữ liệu được đặt tên thay thế các trường được chỉ định bằng các giá trị mới.

Cú pháp

somenamedtuple._replace(kwargs)

Thí dụ

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

Lưu ý : Tên trường không nằm trong dấu ngoặc kép; chúng là những từ khóa ở đây Hãy nhớ rằng : Tuples là bất biến - ngay cả khi chúng được đặt tên và có _replacephương pháp. Việc _replacetạo ra một newví dụ; nó không sửa đổi giá trị gốc hoặc thay thế giá trị cũ. Tất nhiên bạn có thể lưu kết quả mới vào biến.p = p._replace(hue=169)

_make

Tạo một thể hiện mới từ một chuỗi hiện có hoặc lặp lại.

Cú pháp

somenamedtuple._make(iterable)

Thí dụ

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

Điều gì đã xảy ra với người cuối cùng? Mục bên trong dấu ngoặc đơn phải là lần lặp. Vì vậy, một danh sách hoặc bộ dữ liệu bên trong dấu ngoặc đơn hoạt động, nhưng chuỗi các giá trị mà không kèm theo là một lần lặp sẽ trả về một lỗi.

_asdict

Trả về một OrderedDict mới ánh xạ tên trường tới các giá trị tương ứng của chúng.

Cú pháp

somenamedtuple._asdict()

Thí dụ

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

Tham khảo : https://www.reddit.com/r/Python/comments/38ee9d/intro_to_namedtuple/

Ngoài ra còn có danh sách được đặt tên tương tự như tuple được đặt tên nhưng có thể thay đổi https://pypi.python.org/pypi/namedlist


Mặc dù vậy, xin lưu ý rằng, theo PEP8, một dấu gạch dưới đơn lẻ được coi là một chỉ số "sử dụng nội bộ" yếu kém với hành vi của chính nó. Cẩn thận khi sử dụng các chức năng bắt đầu với _!
Jens

8

Tên được đặt tên là gì?

Như tên cho thấy, nametuple là một tuple với tên. Trong bộ dữ liệu tiêu chuẩn, chúng tôi truy cập các phần tử bằng cách sử dụng chỉ mục, trong khi têntuple cho phép người dùng xác định tên cho các phần tử. Điều này rất tiện dụng đặc biệt là xử lý các tệp csv (giá trị được phân tách bằng dấu phẩy) và làm việc với tập dữ liệu lớn và phức tạp, trong đó mã trở nên lộn xộn với việc sử dụng các chỉ mục (không quá pythonic).

Làm thế nào để sử dụng chúng?

>>>from collections import namedtuple
>>>saleRecord = namedtuple('saleRecord','shopId saleDate salesAmout totalCustomers')
>>>
>>>
>>>#Assign values to a named tuple 
>>>shop11=saleRecord(11,'2015-01-01',2300,150) 
>>>shop12=saleRecord(shopId=22,saleDate="2015-01-01",saleAmout=1512,totalCustomers=125)

đọc hiểu

>>>#Reading as a namedtuple
>>>print("Shop Id =",shop12.shopId)
12
>>>print("Sale Date=",shop12.saleDate)
2015-01-01
>>>print("Sales Amount =",shop12.salesAmount)
1512
>>>print("Total Customers =",shop12.totalCustomers)
125

Kịch bản thú vị trong xử lý CSV:

from csv import reader
from collections import namedtuple

saleRecord = namedtuple('saleRecord','shopId saleDate totalSales totalCustomers')
fileHandle = open("salesRecord.csv","r")
csvFieldsList=csv.reader(fileHandle)
for fieldsList in csvFieldsList:
    shopRec = saleRecord._make(fieldsList)
    overAllSales += shopRec.totalSales;

print("Total Sales of The Retail Chain =",overAllSales)

5

Trong Python bên trong có một cách sử dụng tốt container được gọi là tuple có tên, nó có thể được sử dụng để tạo một định nghĩa về lớp và có tất cả các tính năng của bộ dữ liệu gốc.

Sử dụng tuple có tên sẽ được áp dụng trực tiếp vào mẫu lớp mặc định để tạo một lớp đơn giản, phương thức này cho phép rất nhiều mã để cải thiện khả năng đọc và nó cũng rất thuận tiện khi định nghĩa một lớp.


2

Một cách khác (một cách mới) để sử dụng tuple có tên là sử dụng NamedTuple từ cách gõ gói: Nhập gợi ý trong têntuple

Hãy sử dụng ví dụ về câu trả lời hàng đầu trong bài viết này để xem cách sử dụng nó.

(1) Trước khi sử dụng bộ dữ liệu có tên, mã như sau:

pt1 = (1.0, 5.0)
pt2 = (2.5, 1.5)

from math import sqrt
line_length = sqrt((pt1[0]-pt2[0])**2 + (pt1[1]-pt2[1])**2)
print(line_length)

(2) Bây giờ chúng tôi sử dụng bộ dữ liệu có tên

from typing import NamedTuple, Number

kế thừa lớp NamedTuple và định nghĩa tên biến trong lớp mới. kiểm tra là tên của lớp.

class test(NamedTuple):
x: Number
y: Number

tạo các thể hiện từ lớp và gán giá trị cho chúng

pt1 = test(1.0, 5.0)   # x is 1.0, and y is 5.0. The order matters
pt2 = test(2.5, 1.5)

sử dụng các biến từ các thể hiện để tính toán

line_length = sqrt((pt1.x-pt2.x)**2 + (pt1.y-pt2.y)**2)
print(line_length)

1

Thử cái này:

collections.namedtuple()

Về cơ bản, namedtuplesdễ tạo, các loại đối tượng nhẹ. Họ biến bộ dữ liệu thành các thùng chứa thuận tiện cho các nhiệm vụ đơn giản. Với namedtuples, bạn không phải sử dụng các chỉ số nguyên để truy cập các thành viên của một tuple.

Ví dụ:

Mã 1:

>>> from collections import namedtuple

>>> Point = namedtuple('Point','x,y')

>>> pt1 = Point(1,2)

>>> pt2 = Point(3,4)

>>> dot_product = ( pt1.x * pt2.x ) +( pt1.y * pt2.y )

>>> print dot_product
11

Mã 2:

>>> from collections import namedtuple

>>> Car = namedtuple('Car','Price Mileage Colour Class')

>>> xyz = Car(Price = 100000, Mileage = 30, Colour = 'Cyan', Class = 'Y')

>>> print xyz

Car(Price=100000, Mileage=30, Colour='Cyan', Class='Y')
>>> print xyz.Class
Y

-1

Mọi người khác đã trả lời rồi, nhưng tôi nghĩ tôi vẫn còn thứ gì đó để thêm vào.

Namedtuple có thể được coi là trực giác như một phím tắt để xác định một lớp.

Xem một cách rườm rà và thông thường để xác định a 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'

Đối với namedtuple

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'

2
Xin lỗi, nhưng điều này là sai. Các tên tuple cũng hỗ trợ sau đây: red_duck[0]hoặc len(red_duck)hoặc for x in red_duck: print(x). Bên cạnh đó, tên các bộ là không thay đổi, vì vậy các hoạt động này sẽ thất bại: red_duck[0] = 2, red_duck.foo = 'bar'. Vì chúng là bất biến, nên các bộ dữ liệu có tên có thể được sử dụng làm dictkhóa.
Denilson Sá Maia

Vâng, đó là những điều cơ bản.
Giải tích

1
@JawSaw Không, đó không phải là "điều cơ bản". Các bộ dữ liệu được đặt tên hỗ trợ một bộ chức năng hoàn toàn khác so với các lớp thông thường. Mặc dù về bản chất, các bộ dữ liệu có tên là một lớp, điều đó không có nghĩa là các lớp được đặt tên là các bộ dữ liệu.
Trình kết nối
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.