2012-02-27 49 views
15

Hãy nói rằng tôi có trống mảng sau hai chiều bằng Python:Gán giá trị cho một tế bào riêng lẻ trong một mảng hai chiều python

q = [[None]*5]*4 

Tôi muốn gán một giá trị của 5 đến hàng đầu tiên trong lần đầu tiên cột của q. Theo bản năng, tôi làm như sau:

q[0][0] = 5 

Tuy nhiên, điều này tạo ra:

[[5, None, None, None, None], 
    [5, None, None, None, None], 
    [5, None, None, None, None], 
    [5, None, None, None, None]] 

Yếu tố đầu tiên của mỗi mảng được khởi tạo 5, nơi tôi nghĩ chỉ là yếu tố đầu tiên của đầu tiên mảng sẽ nhận được bản cập nhật. Tôi có hai câu hỏi:

  1. Tại sao Python khởi tạo giá trị đầu tiên của mỗi mảng chứ không phải chỉ là giá trị đầu tiên?
  2. Có cách nào tốt hơn để thực hiện những gì tôi đang cố gắng làm không?

Trả lời

31

Điều này không làm những gì bạn mong muốn.

q = [[None]*5]*4 

Nó reuses list đối tượng nhiều lần. Như bạn có thể thấy khi bạn thực hiện thay đổi cho một ô, trong một đối tượng danh sách được sử dụng lại.

Một danh sách duy nhất có giá trị là [None] được sử dụng năm lần.

Một danh sách duy nhất có giá trị là [[None]*5] được sử dụng bốn lần.

q = [ [ None for i in range(5) ] for j in range(4) ] 

Có thể nhiều hơn những gì bạn đang tìm kiếm.

Điều này rõ ràng tránh sử dụng lại đối tượng danh sách.

80% thời gian, từ điển là những gì bạn thực sự muốn.

q = {} 
q[0,0]= 5 

Cũng sẽ hoạt động. Bạn không bắt đầu với lưới được xác định trước là giá trị None. Nhưng hiếm khi cần chúng ngay từ đầu.

Trong Python 2.7 trở lên, bạn có thể thực hiện việc này.

q = { (i,j):0 for i in range(5) for j in range(4) } 

Điều đó sẽ tạo một lưới được lập chỉ mục bởi 2 bộ dữ liệu.

{(0, 1): 0, (1, 2): 0, (3, 2): 0, (0, 0): 0, (3, 3): 0, (3, 0): 0, (3, 1): 0, (2, 1): 0, (0, 2): 0, (2, 0): 0, (1, 3): 0, (2, 3): 0, (4, 3): 0, (2, 2): 0, (1, 0): 0, (4, 2): 0, (0, 3): 0, (4, 1): 0, (1, 1): 0, (4, 0): 0} 
+0

+1 cho từ điển như ma trận. –

+1

Tôi sẽ cung cấp cho bạn +1 nếu bạn chia sẻ nghiên cứu dẫn đến giá trị đó là 80%. –

+2

Đó là Nguyên tắc Pareto. http://en.wikipedia.org/wiki/Pareto_principle. 80% thời gian, bạn chỉ cần 20% cấu trúc dữ liệu. –

5

Lý do bạn có danh sách, chỉ cần nhân đôi bốn lần! Python không tạo lại danh sách đó mỗi khi bạn thực hiện *4. Nó đang sử dụng cùng một đối tượng danh sách.

Để làm được việc này, bạn cần cho lực lượng python để regenrate danh sách đó cho bạn mỗi khi:

[ [None] * 5 for i1 in range(4) ] 

Trong trường hợp này, tôi đang sử dụng một danh sách hiểu.

0

Tại sao Python khởi tạo giá trị đầu tiên của mỗi mảng chứ không phải chỉ là giá trị đầu tiên?

Vì chúng là cùng một mảng, được gọi nhiều lần.

Có cách nào tốt hơn để thực hiện những gì tôi đang cố gắng làm không?

Tạo cấu trúc sao cho mảng bên ngoài đề cập đến mảng bên trong riêng biệt thay vì sử dụng lại một mảng. Các câu trả lời khác cung cấp cách để làm như vậy.

1

Câu trả lời rất đơn giản bao giờ sử dụng

q = [[None]*5]*4 

như khi bạn làm nhiệm vụ

q[0][1]=5 nó gán giá trị nhiều thời gian để nhiều hàng tại 1 cột thử in (q)

thay vì sử dụng

q = { (i,j):0 for i in range(5) for j in range(4) } 

rồi q[0][1]=5 sẽ phân công một lần duy nhất thử

print(q) 
2
q = [[None]*5]*4 
print(q) 
q[1][1]=4 
print(q) 
q = [ [ None for i in range(5) ] for j in range(4) ] 
q[1][1]=4 
print(q) 

kết quả:

[[None, None, None, None, None], [None, None, None, None, None], [None, None, None, None, None], [None, None, None, None, None]] 
[[None, 4, None, None, None], [None, 4, None, None, None], [None, 4, None, None, None], [None, 4, None, None, None]] 
[[None, None, None, None, None], [None, 4, None, None, None], [None, None, None, None, None], [None, None, None, None, None]] 
0

Trong trường hợp bạn muốn sử dụng một danh sách và không phải là một từ điển như những người khác đề nghị bạn có thể sử dụng này:

q[0] = [5,None,None,None,None] 
0

Câu trả lời cho câu hỏi số 2: Sử dụng gọn gàng là một lựa chọn. Xem mã sau.

import numpy as np 

# creating 2D array with nans 
num_of_rows = 5 
num_of_cols = 3 
a = np.full((num_of_rows, num_of_cols), np.nan) 
#for zero vals: a = np.zeros((num_of_rows, num_of_cols)) 

# placing number 5 in row 3, col 1 
value = [5] 
position_row = 3 
position_col = 1 
# the put command below flattens the 2D array 
position = [int(num_of_cols * position_row + position_col)] 
np.put(a, position, value) 

kết quả:

[[ nan nan nan] 
[ nan nan nan] 
[ nan nan nan] 
[ nan 5. nan] 
[ nan nan nan]] 
Các vấn đề liên quan