Danh sách Python có thể lớn đến mức nào?


119

Trong Python, một danh sách có thể lớn đến mức nào? Tôi cần một danh sách khoảng 12000 phần tử. Tôi vẫn có thể chạy các phương pháp danh sách như sắp xếp, v.v.?

Câu trả lời:


193

Theo mã nguồn , kích thước tối đa của một danh sách là PY_SSIZE_T_MAX/sizeof(PyObject*).

PY_SSIZE_T_MAXđược định nghĩa trong pyport.h((size_t) -1)>>1

Trên hệ thống 32 bit thông thường, đây là (4294967295/2) / 4 hoặc 536870912.

Do đó, kích thước tối đa của danh sách python trên hệ thống 32 bit là 536.870.912 phần tử.

Miễn là số phần tử bạn có bằng hoặc thấp hơn mức này, tất cả các hàm danh sách sẽ hoạt động chính xác.


4
Tại sao là sizeof(PyObject*) == 4?? Điều này đại diện cho điều gì?
Matt

4
@Matt, là số byte của một đơn vị PyObject *. Thứ đó được gọi là con trỏ (bạn nhận ra chúng vì có asterix ở cuối). Con trỏ dài 4 byte và lưu trữ một địa chỉ bộ nhớ cho đối tượng được cấp phát. Chúng dài "chỉ" 4 byte vì với 4 byte bạn có thể giải quyết mọi phần tử trong bộ nhớ của máy tính ngày nay.
Antonio Ragagnin

1
Cần lưu ý (như câu trả lời của Álvaro Justen chỉ ra) rằng trên các máy khác, đặc biệt là những máy chạy hệ thống 64-bit, giá trị của PY_SSIZE_T_MAXcó thể rất lớn.
ClydeTheGhost

@ClydeTheGhost, bạn có thể chỉ định liệu những hệ thống 64 bit đang chạy đó cũng có thể có kích thước tối đa thấp hơn 536.870.912 phần tử không? Hoặc chúng có thể khác nhau rất nhiều, nhưng luôn có kích thước tối đa bằng- hoặc lớn hơn 536.870.912 phần tử?
lúc

1
@at Giá trị tối đa cho hệ thống 64 bit sẽ luôn bằng hoặc lớn hơn cho hệ thống 32 bit.
ClydeTheGhost

71

Như tài liệu Python cho biết :

sys.maxsize

Số nguyên dương lớn nhất được hỗ trợ bởi loại Py_ssize_t của nền tảng và do đó danh sách kích thước tối đa, chuỗi, số và nhiều vùng chứa khác có thể có.

Trong máy tính của tôi (Linux x86_64):

>>> import sys
>>> print sys.maxsize
9223372036854775807

như thế nào câu trả lời này câu hỏi
ldgorman

11
@ldgorman, sys.maxsizelà câu trả lời cho câu hỏi. Các kiến ​​trúc khác nhau hỗ trợ các cực đại khác nhau.
Simon Kuang

2
9223372036854775807 phần tử? Có thật không? Điều này cũng thay đổi rất nhiều so với câu trả lời được ủng hộ nhiều nhất.
akki

13
@akki câu trả lời được chấp nhận là đề cập đến hệ thống 32 bit. Vì nó là năm 2016, tôi sẽ cho rằng bạn đang ở trên một hệ thống 64 bit và câu trả lời là do đúng
Brian Leach

2
Đây nên được chọn câu trả lời.
Lokesh

26

Chắc chắn là được. Trên thực tế, bạn có thể thấy cho mình một cách dễ dàng:

l = range(12000)
l = sorted(l, reverse=True)

Chạy những dòng đó trên máy của tôi mất:

real    0m0.036s
user    0m0.024s
sys  0m0.004s

Nhưng chắc chắn như mọi người đã nói. Mảng càng lớn thì các hoạt động sẽ càng chậm.


20
Định thời gian theo cách này có thể gây hiểu nhầm - hầu hết thời gian được dành để khởi động trình thông dịch Python. Một cách tốt hơn là: python -m timeit.py "l = range (12000); l = sorted (l, reverse = True)". Trên máy của tôi, điều này cung cấp khoảng 1/20 thời gian cho ví dụ này.
dF.

5
@dF, Bạn nói đúng về độ chính xác. Cảm ơn vì đã lưu ý điều đó. Tôi chỉ muốn chứng minh một điểm. Và ví dụ chứng minh điều đó.
Nadia Alramli

13
@dF: Tuyệt vời! 0,024 giây là quá lâu đối với tôi và tôi rất vui vì giờ tôi có thể ngừng lo lắng về điều đó.
Thomas Edleson

6

Trong mã thông thường, tôi đã tạo danh sách với hàng triệu phần tử. Tôi tin rằng việc triển khai danh sách của Python chỉ bị ràng buộc bởi dung lượng bộ nhớ trên hệ thống của bạn.

Ngoài ra, các phương thức / chức năng của danh sách sẽ tiếp tục hoạt động bất chấp kích thước của danh sách.

Nếu bạn quan tâm đến hiệu suất, bạn có thể nên xem xét một thư viện chẳng hạn như NumPy .


5

Đặc điểm hiệu suất cho danh sách được mô tả trên Effbot.

Danh sách Python thực sự được triển khai dưới dạng vectơ để truy cập ngẫu nhiên nhanh, vì vậy về cơ bản vùng chứa sẽ chứa nhiều mục nhất là có không gian trong bộ nhớ. (Bạn cần không gian cho các con trỏ có trong danh sách cũng như không gian trong bộ nhớ cho (các) đối tượng được trỏ tới.)

Việc O(1)bổ sung là (độ phức tạp không đổi được phân bổ), tuy nhiên, việc chèn vào / xóa từ giữa dãy sẽ yêu cầu O(n)sắp xếp lại (độ phức tạp tuyến tính), điều này sẽ chậm hơn khi số lượng phần tử trong danh sách của bạn.

Câu hỏi sắp xếp của bạn có nhiều sắc thái hơn, vì thao tác so sánh có thể mất một khoảng thời gian không giới hạn. Nếu bạn thực hiện các phép so sánh thực sự chậm, thì sẽ mất nhiều thời gian, mặc dù đó không phải là lỗi của kiểu dữ liệu danh sách của Python .

Đảo ngược chỉ mất khoảng thời gian cần thiết để hoán đổi tất cả các con trỏ trong danh sách (nhất thiết phải có O(n)(độ phức tạp tuyến tính), vì bạn chạm vào mỗi con trỏ một lần).


4

12000 phần tử không là gì trong Python ... và trên thực tế, số lượng phần tử có thể vượt xa khi trình thông dịch Python có bộ nhớ trên hệ thống của bạn.


3

Nó thay đổi đối với các hệ thống khác nhau (phụ thuộc vào RAM). Cách dễ nhất để tìm ra là

import six six.MAXSIZE 9223372036854775807 Điều này cung cấp kích thước tối đa của listdictquá, theo tài liệu


1
đó không phải là tài liệu
Boris

1

Tôi muốn nói rằng bạn chỉ bị giới hạn bởi tổng dung lượng RAM có sẵn. Rõ ràng là mảng càng lớn thì các thao tác trên nó càng lâu.


4
Nói chung là đúng, nhưng không phải tất cả - cộng dồn vẫn được phân bổ theo thời gian không đổi, độc lập với kích thước của mảng.
cdleary

0

Tôi nhận được điều này từ đây trên hệ thống x64 bit: Python 3.7.0b5 (v3.7.0b5: abb8802389, ngày 31 tháng 5 năm 2018, 01:54:01) [MSC v.1913 64 bit (AMD64)] trên win32

nhập mô tả hình ảnh ở đây


1
Đây sẽ là một câu trả lời tuyệt vời nếu bạn mở rộng một chút về các chi tiết và cách những người khác có thể tìm thấy giới hạn của chính họ.
Shayaan

-16

Không có giới hạn về số lượng danh sách. Nguyên nhân chính gây ra lỗi của bạn là do RAM. Vui lòng nâng cấp kích thước bộ nhớ của bạn.


9
-1 vì nó không thực sự trả lời câu hỏi và thực sự gây hiểu lầm vì (như được hiển thị trong các câu trả lời khác) danh sách thực sự có kích thước tối đa.
ClydeTheGhost
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.