Có gì khác biệt?
Những lợi thế / bất lợi của bộ / danh sách là gì?
list
. ; D
Có gì khác biệt?
Những lợi thế / bất lợi của bộ / danh sách là gì?
list
. ; D
Câu trả lời:
Ngoài các bộ dữ liệu là bất biến, còn có một sự phân biệt ngữ nghĩa nên hướng dẫn việc sử dụng chúng. Các bộ dữ liệu là các cấu trúc dữ liệu không đồng nhất (nghĩa là các mục nhập của chúng có ý nghĩa khác nhau), trong khi các danh sách là các chuỗi đồng nhất. Tuples có cấu trúc, danh sách có thứ tự.
Sử dụng sự phân biệt này làm cho mã rõ ràng và dễ hiểu hơn.
Một ví dụ sẽ là các cặp số trang và số dòng đến các vị trí tham chiếu trong sách, ví dụ:
my_location = (42, 11) # page number, line number
Sau đó, bạn có thể sử dụng khóa này làm khóa trong từ điển để lưu ghi chú trên các vị trí. Mặt khác, một danh sách có thể được sử dụng để lưu trữ nhiều vị trí. Đương nhiên, người ta có thể muốn thêm hoặc xóa các vị trí khỏi danh sách, do đó, có nghĩa là các danh sách có thể thay đổi. Mặt khác, việc thêm hoặc xóa các mục khỏi một vị trí hiện tại là không hợp lý - do đó các bộ dữ liệu là bất biến.
Có thể có tình huống bạn muốn thay đổi các mục trong bộ dữ liệu vị trí hiện tại, ví dụ như khi lặp qua các dòng của trang. Nhưng tuple bất biến buộc bạn phải tạo một tuple vị trí mới cho mỗi giá trị mới. Điều này có vẻ bất tiện trên mặt của nó, nhưng sử dụng dữ liệu bất biến như thế này là nền tảng của các loại giá trị và kỹ thuật lập trình chức năng, có thể có lợi thế đáng kể.
Có một số bài viết thú vị về vấn đề này, ví dụ: "Bộ dữ liệu Python không chỉ là danh sách không đổi" hoặc "Tìm hiểu bộ dữ liệu so với danh sách trong Python" . Tài liệu Python chính thức cũng đề cập đến điều này
"Tuples là bất biến, và thường chứa một chuỗi không đồng nhất ...".
Trong một ngôn ngữ được nhập tĩnh như Haskell, các giá trị trong một tuple thường có các loại khác nhau và độ dài của bộ dữ liệu phải được cố định. Trong một danh sách, tất cả các giá trị đều có cùng loại và độ dài không cố định. Vì vậy, sự khác biệt là rất rõ ràng.
Cuối cùng, có tên làupuple trong Python, điều này có ý nghĩa bởi vì một tuple đã được cho là có cấu trúc. Điều này nhấn mạnh ý tưởng rằng các bộ dữ liệu là một sự thay thế nhẹ cho các lớp và thể hiện.
collections.namedtuple
sẽ được gọi là tốt hơn collections.record
. Sẽ không có ý nghĩa gì khi trao đổi, nói, tên và địa chỉ trong hồ sơ khách hàng; trong thực tế, làm như vậy thường là một lỗi, điều mà tính bất biến của bộ dữ liệu ngăn bạn thực hiện.
What would you do with such a list?
, tôi luôn rùng mình khi ppl sử dụng sự thiếu tưởng tượng làm lý lẽ. Sử dụng danh sách loại hỗn hợp hoạt động rất tốt, ví dụ như đối với một số cấu trúc dữ liệu phân cấp, trong đó mỗi danh sách bao gồm danh sách con và phần tử giá trị.
Sự khác biệt giữa danh sách và bộ dữ liệu
Nghĩa đen
someTuple = (1,2)
someList = [1,2]
Kích thước
a = tuple(range(1000))
b = list(range(1000))
a.__sizeof__() # 8024
b.__sizeof__() # 9088
Do kích thước nhỏ hơn của một thao tác tuple, nó trở nên nhanh hơn một chút, nhưng không có gì nhiều để đề cập đến cho đến khi bạn có một số lượng lớn các yếu tố.
Hoạt động được phép
b = [1,2]
b[0] = 3 # [3, 2]
a = (1,2)
a[0] = 3 # Error
Điều đó cũng có nghĩa là bạn không thể xóa một phần tử hoặc sắp xếp một tuple. Tuy nhiên, bạn có thể thêm một yếu tố mới vào cả danh sách và bộ dữ liệu với sự khác biệt duy nhất là vì bộ dữ liệu này là bất biến, bạn không thực sự thêm một yếu tố nhưng bạn đang tạo một bộ dữ liệu mới, vì vậy id của sẽ thay đổi
a = (1,2)
b = [1,2]
id(a) # 140230916716520
id(b) # 748527696
a += (3,) # (1, 2, 3)
b += [3] # [1, 2, 3]
id(a) # 140230916878160
id(b) # 748527696
Sử dụng
Vì một danh sách có thể thay đổi, nó không thể được sử dụng như một khóa trong từ điển, trong khi một bộ dữ liệu có thể được sử dụng.
a = (1,2)
b = [1,2]
c = {a: 1} # OK
c = {b: 1} # Error
3. Permitted operation
hiển thị trường hợp tuple đầu tiên. Tôi biết nó là bình thường để hiển thị thành công sau đó lỗi, nhưng điều đó làm tôi bối rối trong một vài khoảnh khắc.
one_item_list = [a]
, nhưng one_tuple = (a,)
là bộ dữ liệu tương ứng. Lưu ý dấu phẩy sau tên biến. Nhưng cũng cần lưu ý two_tuple = (a, b)
. Điều này đã ném tôi đi hơn một lần (vẫn còn trong Python 3).
tuple(sorted(the_unsorted_tuple))
Nếu bạn đã đi dạo, bạn có thể lưu ý tọa độ của mình bất cứ lúc nào trong một (x,y)
tuple.
Nếu bạn muốn ghi lại hành trình của mình, bạn có thể nối thêm vị trí của mình cứ sau vài giây vào danh sách.
Nhưng bạn không thể làm điều đó theo cách khác.
Sự khác biệt chính là bộ dữ liệu là bất biến. Điều này có nghĩa là bạn không thể thay đổi các giá trị trong một tuple sau khi bạn đã tạo nó.
Vì vậy, nếu bạn cần thay đổi các giá trị, hãy sử dụng Danh sách.
Lợi ích cho bộ dữ liệu:
frozenset
hoặc các loại cây / cây / đông lạnh của bên thứ ba khác nhau. loại, nhưng không có loại nào cho phép bạn thêm các yếu tố có thể thay đổi. (Và tất nhiên, một tuple chỉ có thể băm nếu tất cả các phần tử của nó, được xử lý theo cách EAFP thông thường, do đó d[1, [2]]
sẽ tăng lên TypeError: unhashable type: 'list'
.)
Danh sách có thể thay đổi; tuples thì không.
Từ docs.python.org/2/tutorial/datastructures.html
Các bộ dữ liệu là bất biến và thường chứa một chuỗi các phần tử không đồng nhất được truy cập thông qua việc giải nén (xem phần sau trong phần này) hoặc lập chỉ mục (hoặc thậm chí theo thuộc tính trong trường hợp được đặt tên). Danh sách có thể thay đổi và các phần tử của chúng thường đồng nhất và được truy cập bằng cách lặp qua danh sách.
Nó đã được đề cập rằng sự khác biệt chủ yếu là về ngữ nghĩa: mọi người mong đợi một tuple và danh sách đại diện cho thông tin khác nhau. Nhưng điều này đi xa hơn một hướng dẫn; một số thư viện thực sự hành xử khác nhau dựa trên những gì họ được thông qua. Lấy NumPy làm ví dụ (được sao chép từ một bài đăng khác nơi tôi hỏi thêm ví dụ):
>>> import numpy as np
>>> a = np.arange(9).reshape(3,3)
>>> a
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
>>> idx = (1,1)
>>> a[idx]
4
>>> idx = [1,1]
>>> a[idx]
array([[3, 4, 5],
[3, 4, 5]])
Vấn đề là, trong khi NumPy có thể không phải là một phần của thư viện tiêu chuẩn, thì đó là một thư viện Python chính và trong danh sách và bộ dữ liệu NumPy là những thứ hoàn toàn khác nhau.
type(a_list) != type(a_tuple)
, do đó, bất kỳ đoạn mã thư viện nào phân nhánh dựa trên type(x)
sẽ hoạt động khác đi
'%d %d' % [2, 3]
là TypeError
vì bạn đang cố gắng chuyển danh sách sang danh sách đầu tiên %d
và bạn không chuyển bất kỳ giá trị nào cho lần thứ hai %d
. (Tuy nhiên, cũng có những ví dụ ngược lại với điều này, như max
Danh sách dành cho vòng lặp, bộ dữ liệu dành cho cấu trúc tức là "%s %s" %tuple
.
Danh sách thường đồng nhất, bộ dữ liệu thường không đồng nhất.
Danh sách dành cho chiều dài thay đổi, bộ dữ liệu dành cho chiều dài cố định.
Đây là một ví dụ về danh sách Python:
my_list = [0,1,2,3,4]
top_rock_list = ["Bohemian Rhapsody","Kashmir","Sweet Emotion", "Fortunate Son"]
Đây là một ví dụ về bộ dữ liệu Python:
my_tuple = (a,b,c,d,e)
celebrity_tuple = ("John", "Wayne", 90210, "Actor", "Male", "Dead")
Danh sách Python và bộ dữ liệu giống nhau ở chỗ cả hai đều được sắp xếp các bộ sưu tập các giá trị. Bên cạnh sự khác biệt nông mà các danh sách được tạo bằng dấu ngoặc "[..., ...]" và bộ dữ liệu sử dụng dấu ngoặc đơn "(..., ...)", sự khác biệt kỹ thuật cốt lõi "được mã hóa theo cú pháp Python" giữa chúng là các yếu tố của một bộ dữ liệu cụ thể là không thay đổi trong khi các danh sách có thể thay đổi (... vì vậy chỉ các bộ dữ liệu có thể băm và có thể được sử dụng làm khóa từ điển / hàm băm!). Điều này dẫn đến sự khác biệt về cách chúng có thể hoặc không thể được sử dụng (thực thi một tiên nghiệm theo cú pháp) và sự khác biệt trong cách mọi người chọn sử dụng chúng (được khuyến khích như là 'cách thực hành tốt nhất', đây là điều mà các lập trình viên thông minh làm). người ta đưa ra thứ tự các yếu tố.
Đối với các bộ dữ liệu, 'thứ tự' biểu thị không gì khác hơn là một 'cấu trúc' cụ thể để lưu giữ thông tin. Những giá trị nào được tìm thấy trong trường đầu tiên có thể dễ dàng được chuyển sang trường thứ hai vì mỗi giá trị cung cấp các giá trị trên hai kích thước hoặc tỷ lệ khác nhau. Họ cung cấp câu trả lời cho các loại câu hỏi khác nhau và thường có dạng: đối với một đối tượng / chủ đề nhất định, thuộc tính của nó là gì? Đối tượng / chủ thể không đổi, các thuộc tính khác nhau.
Đối với danh sách, 'thứ tự' biểu thị một chuỗi hoặc một hướng. Phần tử thứ hai PHẢI đến sau phần tử thứ nhất vì nó được định vị ở vị trí thứ 2 dựa trên quy mô hoặc kích thước cụ thể và chung. Các phần tử được lấy một cách tổng thể và chủ yếu cung cấp câu trả lời cho một câu hỏi duy nhất có dạng, đối với một thuộc tính nhất định, làm thế nào để các đối tượng / đối tượng này so sánh? Thuộc tính không đổi, đối tượng / chủ đề khác nhau.
Có vô số ví dụ về những người trong nền văn hóa và lập trình viên phổ biến không tuân thủ những khác biệt này và có vô số người có thể sử dụng nĩa salad cho món chính của họ. Vào cuối ngày, nó ổn và cả hai thường có thể hoàn thành công việc.
Để tóm tắt một số chi tiết tốt hơn
Điểm tương đồng:
Lập chỉ mục, Chọn và Cắt - Cả bộ dữ liệu và danh sách chỉ mục sử dụng các giá trị số nguyên được tìm thấy trong ngoặc. Vì vậy, nếu bạn muốn 3 giá trị đầu tiên của một danh sách hoặc bộ dữ liệu đã cho, cú pháp sẽ giống nhau:
>>> my_list[0:3]
[0,1,2]
>>> my_tuple[0:3]
[a,b,c]
So sánh & sắp xếp - Hai bộ dữ liệu hoặc hai danh sách đều được so sánh bởi phần tử đầu tiên của chúng và nếu có một ràng buộc, thì bởi phần tử thứ hai, v.v. Không có sự chú ý nào được trả cho các yếu tố tiếp theo sau khi các yếu tố trước đó cho thấy sự khác biệt.
>>> [0,2,0,0,0,0]>[0,0,0,0,0,500]
True
>>> (0,2,0,0,0,0)>(0,0,0,0,0,500)
True
Sự khác biệt: - Một tiên nghiệm, theo định nghĩa
Cú pháp - Danh sách sử dụng [], tuples use ()
Khả năng biến đổi - Các phần tử trong danh sách đã cho là có thể thay đổi, các phần tử trong một bộ dữ liệu đã cho là KHÔNG thể thay đổi.
# Lists are mutable:
>>> top_rock_list
['Bohemian Rhapsody', 'Kashmir', 'Sweet Emotion', 'Fortunate Son']
>>> top_rock_list[1]
'Kashmir'
>>> top_rock_list[1] = "Stairway to Heaven"
>>> top_rock_list
['Bohemian Rhapsody', 'Stairway to Heaven', 'Sweet Emotion', 'Fortunate Son']
# Tuples are NOT mutable:
>>> celebrity_tuple
('John', 'Wayne', 90210, 'Actor', 'Male', 'Dead')
>>> celebrity_tuple[5]
'Dead'
>>> celebrity_tuple[5]="Alive"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
Hashtables (Từ điển) - Vì hashtables (từ điển) yêu cầu các khóa của nó có thể băm và do đó không thay đổi, chỉ các bộ dữ liệu có thể đóng vai trò là khóa từ điển, không phải danh sách.
#Lists CAN'T act as keys for hashtables(dictionaries)
>>> my_dict = {[a,b,c]:"some value"}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
#Tuples CAN act as keys for hashtables(dictionaries)
>>> my_dict = {("John","Wayne"): 90210}
>>> my_dict
{('John', 'Wayne'): 90210}
Sự khác biệt - Một posteriori, trong cách sử dụng
Homo so với sự không đồng nhất của các yếu tố - Nói chung các đối tượng liệt kê là các đối tượng đồng nhất và các đối tượng tuple là không đồng nhất. Đó là, danh sách được sử dụng cho các đối tượng / đối tượng cùng loại (như tất cả các ứng cử viên tổng thống, hoặc tất cả các bài hát hoặc tất cả các vận động viên) trong khi mặc dù nó không bị ép buộc), trong khi các bộ dữ liệu dành cho các đối tượng không đồng nhất.
Looping so với Structures - Mặc dù cả hai đều cho phép lặp (đối với x trong my_list ...), nhưng nó thực sự có ý nghĩa để làm điều đó cho một danh sách. Các bộ dữ liệu phù hợp hơn cho việc cấu trúc và trình bày thông tin (% s% s cư trú trong% s là% s và hiện tại% s% ("John", "Wayne", 90210, "Actor", "Dead"))
Các giá trị của danh sách có thể được thay đổi bất cứ lúc nào nhưng các giá trị của bộ dữ liệu không thể thay đổi.
Những ưu điểm và nhược điểm phụ thuộc vào việc sử dụng. Nếu bạn có một dữ liệu như vậy mà bạn không bao giờ muốn thay đổi thì bạn nên sử dụng bộ dữ liệu, nếu không thì danh sách là lựa chọn tốt nhất.
Các bộ dữ liệu và danh sách đều là các loại trình tự dường như giống nhau trong Python.
Cú pháp
Chúng tôi sử dụng dấu ngoặc đơn ( ) để xây dựng bộ dữ liệu và dấu ngoặc vuông
[ ]
để có danh sách mới. Ngoài ra, chúng ta có thể sử dụng cuộc gọi của loại thích hợp để có được cấu trúc cần thiết - tuple hoặc danh sách.
someTuple = (4,6)
someList = [2,6]
Khả năng biến đổi
Tuples là bất biến, trong khi danh sách là có thể thay đổi. Điểm này là cơ sở cho những người sau đây.
Sử dụng bộ nhớ
Do tính dễ thay đổi, bạn cần thêm bộ nhớ cho danh sách và ít bộ nhớ hơn cho các bộ dữ liệu.
Mở rộng
Bạn có thể thêm một yếu tố mới cho cả bộ dữ liệu và danh sách với sự khác biệt duy nhất là id của bộ dữ liệu sẽ được thay đổi (nghĩa là chúng ta sẽ có một đối tượng mới).
Băm
Tuples có thể băm và danh sách thì không. Nó có nghĩa là bạn có thể sử dụng một tuple làm khóa trong từ điển. Danh sách không thể được sử dụng làm khóa trong từ điển, trong khi đó có thể sử dụng bộ dữ liệu
tup = (1,2)
list_ = [1,2]
c = {tup : 1} # ok
c = {list_ : 1} # error
Ngữ nghĩa
Điểm này là nhiều hơn về thực hành tốt nhất. Bạn nên sử dụng các bộ dữ liệu như các cấu trúc dữ liệu không đồng nhất, trong khi các danh sách là các chuỗi đồng nhất.
Danh sách được dự định là các chuỗi đồng nhất, trong khi các bộ dữ liệu là cấu trúc dữ liệu không đồng nhất.
Như mọi người đã trả lời ở đây tuples
là bất biến trong khi lists
có thể thay đổi, nhưng có một khía cạnh quan trọng của việc sử dụng bộ dữ liệu mà chúng ta phải nhớ
Nếu cái tuple
chứa a list
hoặc a dictionary
bên trong nó, chúng có thể được thay đổi ngay cả khi tuple
bản thân nó là bất biến.
Ví dụ: giả sử chúng ta có một bộ chứa danh sách và từ điển như
my_tuple = (10,20,30,[40,50],{ 'a' : 10})
chúng ta có thể thay đổi nội dung của danh sách như
my_tuple[3][0] = 400
my_tuple[3][1] = 500
mà làm cho tuple mới trông giống như
(10, 20, 30, [400, 500], {'a': 10})
chúng ta cũng có thể thay đổi từ điển bên trong tuple như
my_tuple[4]['a'] = 500
mà sẽ làm cho tổng thể tuple trông giống như
(10, 20, 30, [400, 500], {'a': 500})
Điều này xảy ra bởi vì list
và dictionary
các đối tượng và các đối tượng này không thay đổi, nhưng nội dung mà nó trỏ đến.
Vì vậy, phần tuple
còn lại bất biến mà không có ngoại lệ
Các PEP 484 - Loại gợi ý nói rằng các loại yếu tố của một tuple
có thể được gõ cách cá nhân; để bạn có thể nói Tuple[str, int, float]
; nhưng a list
, với List
lớp gõ có thể chỉ có một tham số loại: List[str]
gợi ý rằng sự khác biệt của 2 thực sự là cái trước không đồng nhất, trong khi cái sau về bản chất là đồng nhất.
Ngoài ra, thư viện tiêu chuẩn chủ yếu sử dụng bộ dữ liệu làm giá trị trả về từ các hàm tiêu chuẩn như vậy trong đó C sẽ trả về a struct
.
Như mọi người đã đề cập đến sự khác biệt, tôi sẽ viết về lý do tại sao các bộ dữ liệu.
Tại sao tuples được ưa thích?
Tối ưu hóa phân bổ cho các bộ dữ liệu nhỏ
Để giảm sự phân mảnh bộ nhớ và tăng tốc độ phân bổ, Python sử dụng lại các bộ dữ liệu cũ. Nếu một tuple không còn cần thiết và có ít hơn 20 mục thay vì xóa vĩnh viễn thì Python sẽ chuyển nó vào một danh sách miễn phí.
Một danh sách miễn phí được chia thành 20 nhóm, trong đó mỗi nhóm đại diện cho một danh sách các bộ dữ liệu có độ dài n trong khoảng từ 0 đến 20. Mỗi nhóm có thể lưu trữ tới 2 000 bộ dữ liệu. Nhóm đầu tiên (không) chỉ chứa 1 phần tử và đại diện cho một bộ dữ liệu trống.
>>> a = (1,2,3)
>>> id(a)
4427578104
>>> del a
>>> b = (1,2,4)
>>> id(b)
4427578104
Trong ví dụ trên chúng ta có thể thấy rằng a và b có cùng id. Đó là bởi vì chúng tôi ngay lập tức chiếm giữ một tuple bị phá hủy nằm trong danh sách miễn phí.
Tối ưu hóa phân bổ cho danh sách
Vì danh sách có thể được sửa đổi, Python không sử dụng tối ưu hóa giống như trong các bộ dữ liệu. Tuy nhiên, danh sách Python cũng có một danh sách miễn phí, nhưng nó chỉ được sử dụng cho các đối tượng trống. Nếu một danh sách trống bị xóa hoặc thu thập bởi GC, nó có thể được sử dụng lại sau này.
>>> a = []
>>> id(a)
4465566792
>>> del a
>>> b = []
>>> id(b)
4465566792
Nguồn: https://rushter.com/blog/python-lists-and-tuples/
Tại sao bộ dữ liệu hiệu quả hơn danh sách? -> https://stackoverflow.com/a/22140115
Một báo giá hướng từ tài liệu trên 5.3. Bộ dữ liệu và trình tự :
Mặc dù các bộ dữ liệu có vẻ giống với danh sách, chúng thường được sử dụng trong các tình huống khác nhau và cho các mục đích khác nhau. Các bộ dữ liệu là bất biến và thường chứa một chuỗi các phần tử không đồng nhất được truy cập thông qua việc giải nén (xem phần sau trong phần này) hoặc lập chỉ mục (hoặc thậm chí theo thuộc tính trong trường hợp được đặt tên). Danh sách có thể thay đổi và các phần tử của chúng thường đồng nhất và được truy cập bằng cách lặp qua danh sách.
Trước hết, cả hai đều là các đối tượng không vô hướng (còn được gọi là các đối tượng ghép) trong Python.
+
(bộ hoàn toàn mới sẽ được tạo ra)(3,) # -> (3)
thay vì(3) # -> 3
[3]
new_array = origin_array[:]
[x**2 for x in range(1,7)]
cho bạn
[1,4,9,16,25,36]
(Không thể đọc được)Sử dụng danh sách cũng có thể gây ra lỗi răng cưa (hai đường dẫn riêng biệt chỉ đến cùng một đối tượng).
Danh sách có thể thay đổi và bộ dữ liệu là bất biến. Chỉ cần xem xét ví dụ này.
a = ["1", "2", "ra", "sa"] #list
b = ("1", "2", "ra", "sa") #tuple
Bây giờ thay đổi giá trị chỉ mục của danh sách và tuple.
a[2] = 1000
print a #output : ['1', '2', 1000, 'sa']
b[2] = 1000
print b #output : TypeError: 'tuple' object does not support item assignment.
Do đó đã chứng minh mã sau đây không hợp lệ với tuple, vì chúng tôi đã cố cập nhật một tuple, không được phép.
Danh sách là đột biến và tuples là bất biến. Sự khác biệt chính giữa có thể thay đổi và không thay đổi là việc sử dụng bộ nhớ khi bạn đang cố gắng nối thêm một mục.
Khi bạn tạo một biến, một số bộ nhớ cố định được gán cho biến đó. Nếu nó là một danh sách, nhiều bộ nhớ được chỉ định hơn thực tế được sử dụng. Ví dụ: nếu gán bộ nhớ hiện tại là 100 byte, khi bạn muốn nối thêm byte thứ 101, có thể 100 byte khác sẽ được chỉ định (trong tổng số 200 byte trong trường hợp này).
Tuy nhiên, nếu bạn biết rằng bạn không thường xuyên thêm các yếu tố mới, thì bạn nên sử dụng bộ dữ liệu. Bộ dữ liệu chỉ định kích thước chính xác của bộ nhớ cần thiết và do đó tiết kiệm bộ nhớ, đặc biệt khi bạn sử dụng các khối bộ nhớ lớn.