2013-07-08 53 views
13

Trong c/C++, chúng ta có thể có:Làm thế nào để thiết lập độ dài tối đa cho một danh sách/bộ python?

maxnum = 10; 
double xlist[maxnum]; 

Làm thế nào để thiết lập chiều dài tối đa cho một danh sách python/thiết lập?

+0

để tôi có thể giới hạn tìm kiếm tham lam của tôi để số x đầu kết quả. Nếu không, đó là loại lãng phí để tiếp tục bổ sung, sắp xếp sau đó xóa các phần tử sau x – alvas

+2

Một cách tiếp cận là tạo lớp tùy chỉnh danh sách và kế thừa chức năng từ python 'list'. Sau đó, trong 'add' (và có thể những người khác) phương pháp thêm một kiểm tra cho chiều dài tối đa. – stalk

+0

@stalk bạn nên đăng câu trả lời đó. –

Trả lời

18

Bạn không cần và không cần.

Danh sách Python phát triển và thu nhỏ động khi cần để vừa với nội dung của chúng. Các bộ được triển khai dưới dạng bảng băm và giống như các từ điển Python phát triển và thu nhỏ động khi cần thiết để phù hợp với nội dung của chúng.

Có lẽ bạn đang tìm kiếm collections.deque (có tham số maxlen) hoặc sử dụng một số heapq (sử dụng heapq.heappushpop() khi bạn đã đạt đến mức tối đa) thay thế?

+0

'dequeue' có thuộc tính' maxlen' cần thực hiện thủ thuật. –

+0

Tôi nghĩ rằng bạn sai về các từ điển bị thu hẹp, hoặc ít nhất nó có phần gây nhầm lẫn. Khi tôi tạo ra một dict trống, 'sys.getsizeof' cho tôi biết nó là 148 byte. Sau khi thêm một triệu mục, đó là 25165876 byte. Sau khi popping tất cả các mục, nó vẫn còn 25165876 byte. Ngoài ra, nếu tôi thử 'next (iter (d))', sau khi thêm hàng triệu mục, nó nhanh hơn khoảng 3500 lần sau khi xuất hiện tất cả, nhưng một (đó là cách tôi nhận thấy điều này). –

+0

@StefanPochmann thay đổi kích thước được hoãn lại cho đến khi bạn thêm lại điều gì đó (IIRC). Tôi cần phải kiểm tra những gì gây nên chính xác. Tôi biết rằng cách sử dụng phổ biến nhất mà bạn xóa thường được theo sau bởi các bổ sung mới được tối ưu hóa cho, do đó không có sự thu hẹp ngay lập tức khi xóa. –

6

Một khi bạn có danh sách của bạn, lst, bạn có thể

if len(lst)>10: 
    lst = lst[:10] 

Nếu kích thước hơn 10 yếu tố, bạn cắt đến mười yếu tố đầu tiên.

+1

khi @JonasR chỉ ra, kiểm tra 'len (lst)' trước khi cắt bớt là thừa. – alvas

+0

tôi không chắc lắm. bạn có thể đúng – octoback

+0

thử mã này 'x = [1,2,6]; x = x [: 2] nếu len (x)> 2 khác x' và sau đó thử mã này 'x = [1,2,6]; x [: 2] ' – alvas

2

Bạn không thể, danh sách và bộ có tính chất động và có thể phát triển ở mọi kích thước.

Python không phải là C++, python là ngôn ngữ động. Bộ và danh sách có thể mở rộng hoặc thu nhỏ thành bất kỳ kích thước nào.

Sử dụng mô-đun heapq nếu bạn muốn x mục nhỏ nhất hoặc lớn nhất từ ​​một lần lặp lại.

heapq.nsmallest(n, iterable[, key]) 

Return một danh sách với các yếu tố n nhỏ nhất từ ​​các tập dữ liệu được xác định bởi iterable. , nếu được cung cấp, chỉ định một hàm của một đối số mà được sử dụng để trích xuất khóa so sánh từ mỗi phần tử trong iterable: key = str.lower Tương đương với: được sắp xếp (iterable, key = key) [: n]

Hoặc có thể bisect mô-đun:

Module này cung cấp hỗ trợ cho việc duy trì một danh sách theo thứ tự sắp xếp mà không cần phải sắp xếp danh sách sau mỗi lần chèn.

Sau đó, sử dụng cắt hoặc itertools.slice để lấy các mục x hàng đầu trong danh sách.

10

Đây là phiên bản mở rộng của python's list. Nó hoạt động như list, nhưng sẽ tăng BoundExceedError, nếu chiều dài vượt quá (cố gắng trong python 2.7):

class BoundExceedError(Exception): 
    pass 


class BoundList(list): 
    def __init__(self, *args, **kwargs): 
     self.length = kwargs.pop('length', None) 
     super(BoundList, self).__init__(*args, **kwargs) 

    def _check_item_bound(self): 
     if self.length and len(self) >= self.length: 
      raise BoundExceedError() 

    def _check_list_bound(self, L): 
     if self.length and len(self) + len(L) > self.length: 
      raise BoundExceedError() 

    def append(self, x): 
     self._check_item_bound() 
     return super(BoundList, self).append(x) 

    def extend(self, L): 
     self._check_list_bound(L) 
     return super(BoundList, self).extend(L) 

    def insert(self, i, x): 
     self._check_item_bound() 
     return super(BoundList, self).insert(i, x) 

    def __add__(self, L): 
     self._check_list_bound(L) 
     return super(BoundList, self).__add__(L) 

    def __iadd__(self, L): 
     self._check_list_bound(L) 
     return super(BoundList, self).__iadd__(L) 

    def __setslice__(self, *args, **kwargs): 
     if len(args) > 2 and self.length: 
      left, right, L = args[0], args[1], args[2] 
      if right > self.length: 
       if left + len(L) > self.length: 
        raise BoundExceedError() 
      else: 
       len_del = (right - left) 
       len_add = len(L) 
       if len(self) - len_del + len_add > self.length: 
        raise BoundExceedError() 
     return super(BoundList, self).__setslice__(*args, **kwargs) 

Cách sử dụng:

>>> l = BoundList(length=10) 
>>> l.extend([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) 
>>> l 
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
>>> # now all these attempts will raise BoundExceedError: 
>>> l.append(11) 
>>> l.insert(0, 11) 
>>> l.extend([11]) 
>>> l += [11] 
>>> l + [11] 
>>> l[len(l):] = [11] 
+0

tôi có cần nhập bất kỳ thư viện hay gì đó không? – alvas

+1

Không, mã này không có phụ thuộc. – stalk