2009-11-27 127 views
10

Tôi đang tìm cách khởi tạo một mảng/danh sách các đối tượng không trống - trình tạo lớp tạo dữ liệu. Trong C++ và Java tôi sẽ làm một cái gì đó như thế này:Khởi tạo danh sách các đối tượng trong Python

Object lst = new Object[100]; 

Tôi đã đào xung quanh, nhưng là có một cách Pythonic để thực hiện điều này?

này không làm việc như tôi nghĩ rằng nó sẽ (tôi nhận được tài liệu tham khảo 100 đến cùng một đối tượng):

lst = [Object()]*100 

Nhưng điều này dường như làm việc theo cách tôi muốn:

lst = [Object() for i in range(100)] 

List comprehension có vẻ (trí tuệ) như "rất nhiều" công việc cho một cái gì đó đơn giản như vậy trong Java.

Trả lời

26

Không có cách nào để ngầm gọi một hàm tạo Object() cho mỗi phần tử của mảng giống như trong C++ (gọi lại trong Java, mỗi phần tử của mảng mới được khởi tạo là null cho kiểu tham chiếu).

Tôi có thể nói rằng phương pháp danh sách hiểu biết của bạn là Pythonic nhất:

lst = [Object() for i in range(100)] 

Nếu bạn không muốn dẫm lên biến từ vựng i, sau đó một quy ước bằng Python là sử dụng _ cho một hình nộm biến có giá trị không quan trọng:

lst = [Object() for _ in range(100)] 

Đối với một tương đương với cấu trúc tương tự như trong Java, bạn có thể sử dụng tất nhiên *:

lst = [None] * 100 
+1

+1. Tôi sẽ đề nghị xrange thay vì phạm vi. – orip

+0

Điểm công bằng; Tôi đã được mã hóa trong Python 3 gần đây. :) –

+1

@orip Trong Python 3, 'range()' làm những gì 'xrange()' được sử dụng để làm và 'xrange()' không tồn tại. Nếu bạn muốn viết mã sẽ chạy trên cả Python 2 và Python 3, bạn không thể sử dụng 'xrange()'. –

0
lst = [Object() for i in range(100)] 

Vì mảng là đối tượng lớp đầu tiên trong python Tôi nghĩ đây là cách duy nhất để có được những gì bạn đang tìm kiếm. * làm điều gì đó điên rồ.

2

Tôi nghĩ rằng việc hiểu danh sách là cách đơn giản nhất, nhưng nếu bạn không thích nó, rõ ràng không phải là cách duy nhất để có được những gì bạn mong muốn - gọi một cuộc gọi được gọi 100 lần mà không có đối số nào để tạo thành 100 các mục của danh sách mới. Ví dụ, itertools rõ ràng có thể làm điều đó:

>>> import itertools as it 
>>> lst = list(it.starmap(Object, it.repeat((), 100))) 

hoặc, nếu bạn thực sự là một truyền thống, mapapply:

>>> lst = map(apply, 100*[Object], 100*[()]) 

Lưu ý rằng điều này về cơ bản là như nhau (nhỏ xíu, cả hai khái niệm và thực sự ;-) số lượng công việc nó sẽ mất nếu, thay vì cần phải được gọi mà không có đối số, Object cần thiết để được gọi với một đối số - hoặc, giả sử, nếu Object thực chất là một hàm chứ không phải là một loại.

Thật ngạc nhiên khi có thể mất "nhiều như một danh sách hiểu" để thực hiện tác vụ này, bạn dường như nghĩ rằng mọi ngôn ngữ cần đặc biệt cần phải thực hiện "cuộc gọi đến một loại, không có đối số" các loại cuộc gọi đến trên các cuộc gọi, nhưng tôi không thấy những điều rất quan trọng và đặc biệt về trường hợp rất cụ thể này, để đảm bảo xử lý nó khác với tất cả những người khác; và, kết quả là, tôi khá hạnh phúc, cá nhân, rằng Python không chỉ dùng một trường hợp này để xử lý kỳ dị và kỳ lạ, nhưng xử lý như thường lệ và dễ dàng như bất kỳ trường hợp sử dụng tương tự nào khác! -)

+0

Tôi cảm thấy rằng bạn đang làm quá nhiều thứ.Một cái gì đó đơn giản như thế này sẽ không yêu cầu nhập khẩu các mô-đun khác – inspectorG4dget

+0

Điểm tốt về trường hợp đặc biệt - Tôi đoán tôi đã không nghĩ về nó từ quan điểm đó. Dòng bản đồ đó thực sự gọn gàng - tôi chưa chơi với bản đồ, vì vậy tôi sẽ phải chơi với nó. – bradreaves

+0

Ah nhưng @Inspector, bạn thấy, giải pháp bản đồ/áp dụng không yêu cầu bất kỳ nhập khẩu nào, nhưng điều đó không làm cho nó ít phức tạp hơn so với công cụ itertools: nó chỉ xảy ra khi sử dụng những thứ cũ đã xảy ra trong nội trang nhiều, nhiều năm trước, trong khi itertools là một ý tưởng mới hơn và được đặt đúng trong mô-đun riêng của nó trong thư viện chuẩn. 'apply' đã biến mất trong Python 3 và' map' đã thay đổi. Vì vậy, bạn thấy: nhận thức của bạn về những gì phức tạp (dựa trên một tiêu chí hoàn toàn không phù hợp như sử dụng nhập khẩu hay không!) Thực sự hoàn toàn, về cơ bản là sai và thất lạc. –

11

bạn nên lưu ý rằng equvalent Python cho mã Java (tạo mảng 100 liệu tham khảo null vào Object):

Object arr = new Object[100]; 

hoặc C++:

Object **arr = new Object*[100]; 

là:

01.
arr = [None]*100 

không:

arr = [Object() for _ in range(100)] 

Thứ hai sẽ được giống như Java:

Object arr = new Object[100]; 
for (int i = 0; i < arr.lenght; i++) { 
    arr[i] = new Object(); 
} 

Trong thực tế khả năng của Python để khởi tạo cấu trúc dữ liệu phức tạp là tốt hơn sau đó của Java.


Lưu ý: C++:

Object *arr = new Object[100]; 

sẽ phải làm càng nhiều việc như danh sách hiểu Python:

  • cấp phát bộ nhớ liên tục cho 100 đối tượng

  • gọi Object :: Object() cho mỗi đối tượng này

Và kết quả sẽ là cấu trúc dữ liệu hoàn toàn khác.

Các vấn đề liên quan