2010-09-07 64 views
10

Có cách nào trong Python để khởi tạo mảng/danh sách đa chiều mà không sử dụng vòng lặp không?Khởi tạo mảng đa chiều Python mà không có vòng lặp

+0

Câu hỏi này hơi mơ hồ: bạn có muốn khởi tạo một mảng đa chiều trống không, hoặc bạn có muốn khởi tạo mảng đa chiều cho một tập hợp giá trị cụ thể không? –

Trả lời

12

chắc có một cách

arr = eval(`[[0]*5]*10`) 
.210

hoặc

arr = eval(("[[0]*5]+"*10)[:-1]) 

nhưng nó kinh khủng và lãng phí, vì vậy tất cả mọi người sử dụng các vòng lặp (thường là danh sách comprehensions) hoặc NumPy

+0

Đánh dấu là được chấp nhận là phản ánh tốt nhất câu hỏi. numpy không phải là một phần của cài đặt Python chuẩn. – Leonid

+1

Điều này có nhược điểm khi tạo tham chiếu đến cùng một đối tượng, xem [câu trả lời này] (http://stackoverflow.com/a/3662548/393885) –

+1

@black_puppydog, không có. Đó là lý do tại sao 'eval' được sử dụng ở đây –

2

Nó phụ thuộc vào những gì bạn cần khởi tạo mảng, nhưng chắc chắn. Bạn có thể sử dụng danh sách hiểu biết để tạo ra một mảng 5 × 3, ví dụ:

>>> [[0 for x in range(3)] for y in range(5)] 
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]] 

>>> [[3*y+x for x in range(3)] for y in range(5)] 
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11], [12, 13, 14]] 

Vâng, tôi cho rằng điều này vẫn có vòng — nhưng đó là tất cả được thực hiện trong một dòng, mà tôi đoán là ý nghĩa dự định của bạn câu hỏi?

+3

Điều đó không được tính là sử dụng vòng lặp? –

+0

Tài liệu chỉ định nó như một cách để khởi tạo danh sách đa chiều. Đối với một danh sách một chiều, khởi tạo sau đây là có thể 'list = [5] * 10', nhưng không thể làm cho nó hoạt động với nhiều thứ nguyên hơn. Có vẻ như khi bạn làm 'list = [[5] * 5] * 5', thì mỗi chiều phụ sẽ trỏ đến cùng một bộ nhớ, đó không phải là thứ tôi muốn. – Leonid

5

Chắc chắn, bạn chỉ có thể làm

mylist = [ 
      [1,2,3], 
      [4,5,6], 
      [7,8,9] 
     ] 
+3

Bạn hoàn toàn đúng, và tôi không hỏi làm thế nào mà sẽ tìm kiếm một ma trận 1000 X 1000 ... – Leonid

9

Tùy thuộc vào nhu cầu thực sự của bạn, de facto "chuẩn" gói Numpy có thể cung cấp cho bạn chính xác những gì bạn cần.

Bạn có thể ví dụ như tạo ra một mảng đa chiều với

numpy.empty((10, 4, 100)) # 3D array 

(khởi tạo với giá trị tùy ý) hoặc tạo các mảng cùng với số không khắp mọi nơi với

numpy.zeros((10, 4, 100)) 

NumPy là rất nhanh, cho các hoạt động mảng.

+0

Hm ... cả hai ví dụ này có tạo ra một mảng 10 x 4 x 100 không? –

+1

Họ chắc chắn nhất làm. Bạn có thể kiểm tra điều này bằng cách thực hiện 'a = numpy.empty ((10, 4, 100)); in a.shape'. – EOL

3

Tôi không tin điều đó là có thể.

Bạn có thể làm một cái gì đó như thế này:

>>> a = [[0] * 5] * 5 

để tạo ra một ma trận 5x5, nhưng nó được lặp lại đối tượng (mà bạn không muốn). Ví dụ:

>>> a[1][2] = 1 
[[0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0]] 

Bạn gần như chắc chắn cần phải sử dụng một số loại vòng lặp như trong:

[[0 for y in range(5)] for x in range(5)] 
+1

>>> a = [[0] * 5] * 5 Đó là một chút nguy hiểm cách .. có lẽ nó là tốt nếu bạn sử dụng số không. Nhưng nếu bạn cố gắng đặt biến đó vào đó. Bạn nhận danh sách các danh sách tham chiếu đến cùng một giá trị. ví dụ khi bạn đặt [1] [1] = 5 - tất cả danh sách sẽ có mục ở 1 vị trí là 5! – RredCat

1

Nếu bạn đang làm việc số sử dụng numpy, một cái gì đó giống như

x = numpy.zeros ((m,n)) 
x = numpy.ones ((m,n)) 
3

Đệ quy là bạn của bạn: D

Đó là một thực hiện khá ngây thơ nhưng nó hoạt động !

dim = [2, 2, 2] 

def get_array(level, dimension): 
    if(level != len(dimension)): 
     return [get_array(level+1, dimension) for i in range(dimension[level])] 
    else: 
     return 0 

print get_array(0, dim) 
+0

Đây chỉ là những gì tôi đã làm sau, cảm ơn!Lời nhắc duy nhất của tôi là tôi muốn gửi xuống một mảng chiều ngắn, thay vì hai tham số, như sau: [get_array (dimension [1:]) cho j trong xrange (dimension [0])] – Jaime

1

Python không có mảng. Nó có các loại trình tự khác nhau, từ danh sách đến từ điển mà không quên bộ - một trong những quyền phụ thuộc vào nhu cầu cụ thể của bạn.

Giả sử "mảng" của bạn thực sự là một danh sách, và "khởi tạo" có nghĩa là phân bổ một danh sách liệt kê của NxM yếu tố, bạn có thể (giả):

  • cho N lần: cho M lần: thêm một yếu tố
  • cho N lần: thêm một hàng của các nguyên tố M
  • viết toàn bộ điều ra

bạn nói rằng bạn không muốn lặp và rằng những quy tắc ra linh sam st hai điểm, nhưng tại sao? Bạn cũng nói rằng bạn không muốn viết điều xuống (để đáp ứng với JacobM), vậy làm thế nào bạn sẽ chính xác làm điều đó? Tôi không biết cách nào khác để có được một cấu trúc dữ liệu mà không cần tạo ra nó trong các phần nhỏ hơn (lặp lại) hoặc viết nó xuống một cách rõ ràng - bằng bất kỳ ngôn ngữ lập trình nào.

Cũng xin lưu ý rằng danh sách được khởi tạo nhưng trống không tốt hơn là không có danh sách, trừ khi bạn đặt dữ liệu vào đó. Và bạn không cần phải khởi tạo nó trước khi đặt dữ liệu ...

Nếu đây không phải là bài tập lý thuyết, có lẽ bạn đang đặt câu hỏi sai. Tôi đề nghị bạn giải thích bạn cần làm gì với mảng đó.

+0

Bạn sẽ thâm nhập sâu vào một số của các điểm :)) Điểm của câu hỏi là rất đơn giản và nó yêu cầu những gì nó yêu cầu. Tôi đã tự hỏi về các kỹ thuật khác nhau mà mọi người sử dụng để khởi tạo danh sách ** đa chiều ** và câu trả lời cho câu hỏi đó phản ánh hoàn toàn những gì tôi muốn biết. Một số người sử dụng thư viện Numpy tiêu chuẩn * de-facto *. Một số người khởi tạo danh sách bằng cách sử dụng 'for' vòng rõ ràng. Như * JacobM * cho thấy bạn có thể khởi tạo tĩnh các danh sách, nhưng tôi chỉ ra rằng nó không áp dụng cho các danh sách lớn. * gnibbler * cho thấy cách rất thú vị nhưng sôi nổi và không hiệu quả. – Leonid

+0

Tôi đặc biệt băn khoăn về việc khởi tạo mà không có vòng lặp 'for', vì nó đã rõ ràng từ các tài liệu như thế nào bạn sẽ làm điều đó. – Leonid

1
a = [[]] 
a.append([1,2]) 
a.append([2,3]) 

Sau đó

>>> a 
[[1, 2], [2, 3]] 
3

Sau đây không sử dụng bất kỳ thư viện đặc biệt, cũng không eval:

arr = [[0]*5 for x in range(6)] 

và nó không tạo ra tài liệu tham khảo trùng lặp:

>>> arr[1][1] = 2 
>>> arr 
[[0, 0, 0, 0, 0], 
[0, 2, 0, 0, 0], 
[0, 0, 0, 0, 0], 
[0, 0, 0, 0, 0], 
[0, 0, 0, 0, 0], 
[0, 0, 0, 0, 0]] 
Các vấn đề liên quan