Chúng giống như một cách hiểu danh sách, nhưng nó không lưu trữ các giá trị của nó trên bộ nhớ, nó chỉ tạo ra giá trị mà bạn đang lặp lại khi trình tạo được gọi
Để kiểm tra giá trị trên trình tạo, bạn có thể lặp qua trình tạo bằng vòng lặp for hoặc bạn có thể kiểm tra giá trị bằng toán tử next[]
t=[i**2 for i in range[10]]#accessing through the next operator
next[b]
0 #returns the first element of the tuple
next[b]
1 #returns the second element of the tuple
Bằng cách sử dụng hàm next[], bạn có thể kiểm tra tất cả các giá trị cho đến giá trị cuối cùng, nếu bạn muốn kiểm tra tất cả cùng một lúc, bạn cũng có thể lặp qua toán tử for
t=[i**2 for i in range[10]]Việc hiểu tuple có hiệu quả hơn hiểu danh sách không?
for i in t:
print[t]0
1
4
9
16
25
36
49
64
81
vâng, hiểu tuple là hiệu quả. Trong danh sách, nó lưu trữ tất cả các phần tử trong bộ nhớ và nó tiêu tốn rất nhiều bộ nhớ nhưng khi nói đến bộ dữ liệu, nó chỉ lưu trữ phần tử được gọi nên nó tiết kiệm bộ nhớ
import sys
x = [i**2 for i in range[10000]] #list
print[sys.getsizeof[x]]87632y = [i**2 for i in range[10000]] #tuple
print[sys.getsizeof[y]]128
Nếu chúng ta lấy một danh sách tương tự và tuple và kiểm tra kích thước của nó bằng sys. getsizeof[] chúng ta có thể thấy rằng tuple đang tiêu thụ ít bộ nhớ hơn so với danh sách
Thứ nhất, bộ dữ liệu thường không được sử dụng để lưu trữ một chuỗi dữ liệu đồng nhất. Chúng tôi sử dụng nó thường xuyên hơn để lưu trữ dữ liệu không đồng nhất như một cách nhanh chóng để nhóm các dữ liệu liên quan lại với nhau
Thứ hai, chúng tôi tạo một tuple với dấu ngoặc tròn.
# with brackets
t1 = [1, 2, 3]
# outputs: [1, 2, 3]
# without brackets
t2 = 8,9
# outputs: [8, 9]
1, vì vậy khả năng hiểu bộ dữ liệu có thể sẽ giống như thế nàymy_tuple = [item for item in some_iterable]
Nhưng cú pháp này đã được sử dụng cho các biểu thức trình tạo. Vì vậy, đoạn mã trên trả về một đối tượng trình tạo. Chúng ta sẽ thảo luận về biểu thức trình tạo vào lúc khác. [Nếu bạn chưa biết chúng là gì, đừng lo lắng, bạn có thể tiến xa mà không cần chúng. ]
Tại sao chúng ta có thể cần nó?Permalink
Đôi khi chúng tôi muốn lưu trữ dữ liệu đồng nhất trong một tuple
Một lý do có thể là không có danh sách bất biến [đóng băng] trong Python [không có trong thư viện chuẩn]. Một số nhóm muốn có loại bộ sưu tập bất biến thay cho danh sách để đảm bảo rằng danh sách sau khi được tạo sẽ không bị thay đổi
Tuple phù hợp với yêu cầu này. Nó hoạt động như một danh sách và có tất cả các đặc điểm của danh sách khi đọc một bộ. [Và thế là đủ vì nó là bất biến nên chúng ta không muốn ghi vào nó]
Vậy chúng ta có thể làm gì nếu muốn sử dụng một tuple thay vì một danh sách nhưng vẫn tận hưởng vẻ đẹp của một sự hiểu biết?
Chúng ta có thể hiểu tuple [gần như]Permalink
Ok, vậy làm thế nào chúng ta có thể hiểu tuple?
Thông thường, một bộ dữ liệu chỉ được xây dựng với dấu ngoặc tròn hoặc thậm chí không có
# with brackets
t1 = [1, 2, 3]
# outputs: [1, 2, 3]
# without brackets
t2 = 8,9
# outputs: [8, 9]
Nhưng một bộ là một lớp [đối tượng] thích hợp, vì vậy chúng ta cũng có thể tạo một bộ như bất kỳ đối tượng nào khác - khởi tạo nó bằng tên lớp của nó
t3 = tuple[]
t3
# outputs: []
Được rồi, điều này không hữu ích. Chúng ta hãy xem tài liệu để xem lớp tuple trông như thế nào.
Vì vậy, tuple có thể được xây dựng bằng cách sử dụng lớp tuple và truyền cho nó một số lần lặp, e. g. danh sách
t4 = tuple[[22, 33]]
t4
# outputs: [22, 33]
Nếu cần một danh sách, chúng ta cũng có thể sử dụng khả năng hiểu danh sách
________số 8Mã này hơi dài;
Nó cũng phân bổ bộ nhớ cho tất cả các mục mà chúng ta muốn có trong một bộ dữ liệu hai lần. Trước tiên, chúng tôi tạo một danh sách [cấp phát bộ nhớ], sau đó được sử dụng để tạo một bộ dữ liệu có cùng các mục [cấp phát lại bộ nhớ]. Có, bộ nhớ cho danh sách được giải phóng ngay sau khi bộ dữ liệu được tạo, nhưng bộ nhớ vẫn cần khả dụng
Chúng ta có thể làm tốt hơn
Như đã thấy trong tài liệu, một tuple chấp nhận iterable làm đối số
Như tài liệu nói
iterable có thể là một chuỗi, một vùng chứa hỗ trợ phép lặp hoặc một đối tượng lặp
Iterator là một đối tượng cho phép chúng ta lặp lại [traverse] qua một iterable, nhưng nó cũng có thể lặp lại chính nó
Chúng tôi không muốn cấp phát bộ nhớ cho tất cả các mục một cách không cần thiết; . Trình tạo tạo một giá trị tại một thời điểm [thay vì cấp phát bộ nhớ cho tất cả các mục]
Và cách dễ nhất để tạo trình tạo là sử dụng biểu thức trình tạo
[n * 2 for n in numbers]
# outputs
Chúng tôi có thể sử dụng điều này trực tiếp khi tạo bộ dữ liệu của mình
t=[i**2 for i in range[10]]0
for i in t:
print[t]0
1
4
9
16
25
36
49
64
81
Điều đó tốt hơn [về bộ nhớ], nhưng vẫn còn rất nhiều dấu ngoặc
May mắn thay, biểu thức trình tạo không cần phải được đặt trong ngoặc đơn nếu nó là đối số duy nhất trong hàm nên chúng ta có thể viết nó như thế này
t=[i**2 for i in range[10]]1
for i in t:
print[t]0
1
4
9
16
25
36
49
64
81
Và đó là nó. Điều đó gần với sự hiểu biết về bộ dữ liệu nhất mà chúng ta có thể nhận được. Nó yêu cầu sử dụng
# with brackets
t1 = [1, 2, 3]
# outputs: [1, 2, 3]
# without brackets
t2 = 8,9
# outputs: [8, 9]
2 trước "hiểu" của chúng tôi, nhưng nếu không thì nó giống nhau. Nó cũng là bộ nhớ hiệu quả. Nó không tạo một danh sách và sau đó là một bộ, vì vậy nó không cấp phát bộ nhớ một cách không cần thiếtHiệu SuấtPermalink
Tôi có vài tin xấu đây. Nó chậm hơn so với hiểu danh sách
Đây là phép đo đơn giản để hiểu danh sách tạo danh sách từ 100 số và nhân đôi mỗi số
t=[i**2 for i in range[10]]3
for i in t:
print[t]0
1
4
9
16
25
36
49
64
81
3. 4 micro giây
Và đây là phép đo khi chúng ta tạo một tuple thay vào đó, sử dụng trình tạo của chúng ta
t=[i**2 for i in range[10]]4
for i in t:
print[t]0
1
4
9
16
25
36
49
64
81
4. 79 micro giây. Vì vậy, nó chậm hơn khoảng 40%
Hãy thử một phiên bản trong đó chúng tôi tạo một bộ dữ liệu bằng cách chuyển cho nó một cách hiểu danh sách
# with brackets
t1 = [1, 2, 3]
# outputs: [1, 2, 3]
# without brackets
t2 = 8,9
# outputs: [8, 9]
03. 6 micro giây. Vì vậy, phiên bản này vẫn thực thi nhanh hơn so với phiên bản có trình tạo và chúng tôi vẫn kết thúc với một bộ dữ liệu. Như đã đề cập trước đó, nó phân bổ bộ nhớ hai lần, vì vậy hãy cẩn thận khi làm việc với dữ liệu lớn
Hiệu suất [hoặc mức sử dụng bộ nhớ] là cái giá chúng ta phải trả nếu muốn sử dụng một bộ làm danh sách bất biến