Trong Python, cấu trúc dữ liệu nào hiệu quả / nhanh hơn? Giả sử rằng thứ tự đó không quan trọng đối với tôi và dù sao tôi cũng sẽ kiểm tra các bản sao, liệu Python có chậm hơn danh sách Python không?
Trong Python, cấu trúc dữ liệu nào hiệu quả / nhanh hơn? Giả sử rằng thứ tự đó không quan trọng đối với tôi và dù sao tôi cũng sẽ kiểm tra các bản sao, liệu Python có chậm hơn danh sách Python không?
Câu trả lời:
Nó phụ thuộc vào những gì bạn đang có ý định làm với nó.
Các bộ nhanh hơn đáng kể khi xác định xem một đối tượng có trong tập hợp không (như trong x in s
) hay không, nhưng chậm hơn các danh sách khi nói về việc lặp lại nội dung của chúng.
Bạn có thể sử dụng mô-đun thời gian để xem cái nào nhanh hơn cho tình huống của bạn.
Danh sách nhanh hơn một chút so với các tập hợp khi bạn chỉ muốn lặp lại các giá trị.
Tuy nhiên, các bộ nhanh hơn đáng kể so với danh sách nếu bạn muốn kiểm tra xem một mục có được chứa trong đó không. Chúng chỉ có thể chứa các mặt hàng độc đáo mặc dù.
Hóa ra các bộ dữ liệu thực hiện theo cách gần như chính xác như các danh sách, ngoại trừ tính bất biến của chúng.
Lặp đi lặp lại
>>> def iter_test(iterable):
... for i in iterable:
... pass
...
>>> from timeit import timeit
>>> timeit(
... "iter_test(iterable)",
... setup="from __main__ import iter_test; iterable = set(range(10000))",
... number=100000)
12.666952133178711
>>> timeit(
... "iter_test(iterable)",
... setup="from __main__ import iter_test; iterable = list(range(10000))",
... number=100000)
9.917098999023438
>>> timeit(
... "iter_test(iterable)",
... setup="from __main__ import iter_test; iterable = tuple(range(10000))",
... number=100000)
9.865639209747314
Xác định nếu một đối tượng có mặt
>>> def in_test(iterable):
... for i in range(1000):
... if i in iterable:
... pass
...
>>> from timeit import timeit
>>> timeit(
... "in_test(iterable)",
... setup="from __main__ import in_test; iterable = set(range(1000))",
... number=10000)
0.5591847896575928
>>> timeit(
... "in_test(iterable)",
... setup="from __main__ import in_test; iterable = list(range(1000))",
... number=10000)
50.18339991569519
>>> timeit(
... "in_test(iterable)",
... setup="from __main__ import in_test; iterable = tuple(range(1000))",
... number=10000)
51.597304821014404
Danh sách hiệu suất:
>>> import timeit
>>> timeit.timeit(stmt='10**6 in a', setup='a = range(10**6)', number=100000)
0.008128150348026608
Đặt hiệu suất:
>>> timeit.timeit(stmt='10**6 in a', setup='a = set(range(10**6))', number=100000)
0.005674857488571661
Bạn có thể muốn xem xét Tuples vì chúng giống với danh sách nhưng không thể sửa đổi. Chúng chiếm ít bộ nhớ hơn và truy cập nhanh hơn. Chúng không linh hoạt nhưng hiệu quả hơn danh sách. Sử dụng bình thường của họ là để phục vụ như các khóa từ điển.
Các bộ cũng là cấu trúc trình tự nhưng có hai điểm khác biệt từ danh sách và bộ dữ liệu. Mặc dù các tập hợp có một thứ tự, thứ tự đó là tùy ý và không thuộc quyền kiểm soát của lập trình viên. Sự khác biệt thứ hai là các yếu tố trong một bộ phải là duy nhất.
set
theo định nghĩa. [ trăn | wiki ].
>>> x = set([1, 1, 2, 2, 3, 3])
>>> x
{1, 2, 3}
set
liên kết loại tích hợp ( docs.python.org/2/l Library / stdtypes.html # set ) chứ không phải sets
thư viện không dùng nữa . Thứ hai, "Bộ cũng là cấu trúc trình tự", đọc phần sau từ liên kết loại tích hợp: "Là bộ sưu tập không có thứ tự, các bộ không ghi vị trí phần tử hoặc thứ tự chèn. Theo đó, các bộ không hỗ trợ lập chỉ mục, cắt hoặc khác hành vi giống như trình tự. "
range
không phải là list
. range
là một lớp học đặc biệt với __contains__
phương pháp ma thuật tùy chỉnh .
xrange
)
Set
chiến thắng do gần như ngay lập tức 'chứa' séc: https://en.wikipedia.org/wiki/Hash_table
Danh sách thực hiện: thường là một mảng, mức độ thấp gần với kim loại, tốt cho việc lặp lại và truy cập ngẫu nhiên theo chỉ số phần tử.
Đặt triển khai: https://en.wikipedia.org/wiki/Hash_table , nó không lặp lại trong danh sách, nhưng tìm phần tử bằng cách tính băm từ khóa, vì vậy nó phụ thuộc vào bản chất của các phần tử chính và hàm băm chức năng. Tương tự như những gì được sử dụng cho dict. Tôi nghi ngờ list
có thể nhanh hơn nếu bạn có rất ít yếu tố (<5), yếu tố càng lớn thì khả năng set
thực hiện đối với kiểm tra có chứa càng tốt . Nó cũng nhanh chóng để thêm và loại bỏ yếu tố. Cũng luôn luôn nhớ rằng xây dựng một bộ có chi phí!
LƯU Ý : Nếu list
đã được sắp xếp, việc tìm kiếm list
có thể khá nhanh, nhưng đối với các trường hợp thông thường, a set
sẽ nhanh hơn và đơn giản hơn để chứa séc.
Cấu trúc dữ liệu (DS) rất quan trọng vì chúng được sử dụng để thực hiện các thao tác trên dữ liệu về cơ bản ngụ ý: lấy một số đầu vào , xử lý nó và trả lại đầu ra .
Một số cấu trúc dữ liệu hữu ích hơn những cấu trúc khác trong một số trường hợp cụ thể. Do đó, thật không công bằng khi hỏi (DS) nào hiệu quả / nhanh hơn. Nó giống như hỏi công cụ nào hiệu quả hơn giữa dao và nĩa. Ý tôi là tất cả phụ thuộc vào tình hình.
Một danh sách là chuỗi có thể thay đổi , thường được sử dụng để lưu trữ các bộ sưu tập các mặt hàng đồng nhất .
Một đối tượng được thiết lập là một bộ sưu tập các đối tượng có thể băm riêng biệt . Nó thường được sử dụng để kiểm tra tư cách thành viên, loại bỏ các bản sao khỏi chuỗi và tính toán các phép toán như giao điểm, liên kết, chênh lệch và chênh lệch đối xứng.
Từ một số câu trả lời, rõ ràng một danh sách khá nhanh hơn một tập hợp khi lặp qua các giá trị. Mặt khác, một bộ nhanh hơn một danh sách khi kiểm tra xem một mục có được chứa trong đó không. Do đó, điều duy nhất bạn có thể nói là một danh sách tốt hơn một bộ cho một số hoạt động cụ thể và ngược lại.
Tôi đã quan tâm đến kết quả khi kiểm tra, với CPython, nếu một giá trị là một trong số ít chữ. set
thắng bằng Python 3 vs tuple
, list
và or
:
from timeit import timeit
def in_test1():
for i in range(1000):
if i in (314, 628):
pass
def in_test2():
for i in range(1000):
if i in [314, 628]:
pass
def in_test3():
for i in range(1000):
if i in {314, 628}:
pass
def in_test4():
for i in range(1000):
if i == 314 or i == 628:
pass
print("tuple")
print(timeit("in_test1()", setup="from __main__ import in_test1", number=100000))
print("list")
print(timeit("in_test2()", setup="from __main__ import in_test2", number=100000))
print("set")
print(timeit("in_test3()", setup="from __main__ import in_test3", number=100000))
print("or")
print(timeit("in_test4()", setup="from __main__ import in_test4", number=100000))
Đầu ra:
tuple
4.735646052286029
list
4.7308746771886945
set
3.5755991376936436
or
4.687681658193469
Trong 3 đến 5 chữ, set
vẫn thắng với tỷ lệ chênh lệch cao và or
trở thành chậm nhất.
Trong Python 2, set
luôn là chậm nhất. or
là nhanh nhất cho 2-3 literals, và tuple
và list
nhanh hơn với 4 hoặc nhiều chữ. Tôi không thể phân biệt tốc độ của tuple
vs list
.
Khi các giá trị cần kiểm tra được lưu trong bộ biến toàn cục ngoài hàm, thay vì tạo ra chữ trong vòng lặp, sẽ set
giành chiến thắng mọi lúc, ngay cả trong Python 2.
Những kết quả này áp dụng cho CPython 64 bit trên Core i7.
Tôi muốn giới thiệu Cài đặt thực hiện trong đó trường hợp sử dụng là giới hạn đối với tham chiếu hoặc tìm kiếm sự tồn tại và triển khai Tuple trong đó trường hợp sử dụng yêu cầu bạn thực hiện phép lặp. Một danh sách là một triển khai cấp thấp và đòi hỏi chi phí bộ nhớ đáng kể.
from datetime import datetime
listA = range(10000000)
setA = set(listA)
tupA = tuple(listA)
#Source Code
def calc(data, type):
start = datetime.now()
if data in type:
print ""
end = datetime.now()
print end-start
calc(9999, listA)
calc(9999, tupA)
calc(9999, setA)
Đầu ra sau khi so sánh 10 lần lặp cho cả 3: So sánh
Các bộ nhanh hơn, điều chỉnh bạn nhận được nhiều chức năng hơn với các bộ, chẳng hạn như giả sử bạn có hai bộ:
set1 = {"Harry Potter", "James Bond", "Iron Man"}
set2 = {"Captain America", "Black Widow", "Hulk", "Harry Potter", "James Bond"}
Chúng ta có thể dễ dàng tham gia hai bộ:
set3 = set1.union(set2)
Tìm hiểu những gì phổ biến trong cả hai:
set3 = set1.intersection(set2)
Tìm hiểu những gì là khác nhau trong cả hai:
set3 = set1.difference(set2)
Và nhiều hơn nữa! Chỉ cần thử chúng ra, chúng rất vui! Ngoài ra, nếu bạn phải làm việc với các giá trị khác nhau trong 2 danh sách hoặc các giá trị chung trong 2 danh sách, tôi thích chuyển đổi danh sách của bạn thành các bộ và nhiều lập trình viên thực hiện theo cách đó. Hy vọng nó sẽ giúp bạn :-)