2010-03-24 58 views
12

tôi có một danh sách, chúng ta hãy nói, a = [[1,2],[3,4],[5,6]]Phụ thêm mục vào danh sách trong danh sách hiểu

tôi muốn thêm vào chuỗi 'a' cho mỗi mục trong danh sách a.

Khi tôi sử dụng:

a = [x.append('a') for x in a] 

nó trả [None,None,None].

Nhưng nếu tôi sử dụng:

a1 = [x.append('a') for x in a] 

sau đó nó làm điều gì đó kỳ lạ.

a, nhưng không phải a1[[1,2,'a'],[3,4,'a'],[5,6,'a']].

Tôi không hiểu tại sao cuộc gọi đầu tiên trả lại [None, None, None] cũng như lý do thay đổi thứ hai trên a thay vì a1.

Trả lời

7

Đối với trường hợp đầu tiên, lý do nó sẽ trả về [None, None, None] là do list.append hàm trả None, và đó là những gì nó sẽ lưu trong danh sách.

Trong trường hợp thứ hai, đó là do danh sách có thể thay đổi và mỗi lần bạn thêm giá trị, danh sách gốc sẽ được sửa đổi.

Những gì bạn cần là toán tử phụ không có tại chỗ, chẳng hạn như +. tức là [x + ['a'] for x in a].

23

list.append tự tắt danh sách và trả về None. Danh sách hiểu được là để lưu trữ kết quả, mà không phải là những gì bạn muốn trong trường hợp này nếu bạn muốn chỉ cần thay đổi danh sách ban đầu.

>>> x = [[1, 2], [3, 4], [5, 6]] 
>>> for sublist in x: 
...  sublist.append('a') 
... 
>>> x 
[[1, 2, 'a'], [3, 4, 'a'], [5, 6, 'a']] 
3

(Đây là một sự kết hợp của các câu trả lời bằng Mike Graham và sykora):

Nếu bạn chỉ đơn thuần muốn thay đổi các giá trị tại chỗ, hãy thử một thường xuyên cho vòng lặp, và không phải là một danh sách hiểu :

for sublist in a: 
    sublist.append('a') 

Nếu bạn muốn để lại một mình, và đặt kết quả trong a1:

a1 = [sublist + ['a'] for sublist in a] 

Khi họ giải thích, append sửa đổi danh sách, nhưng trả về Không, trong khi + để lại danh sách một mình, nhưng trả về một danh sách mới, được nối thêm.

+3

Đó phải là a1 = [danh sách phụ + ['a'] cho danh sách phụ trong a]. Lưu ý các dấu ngoặc xung quanh 'a'. –

+0

Rất tiếc. Đã sửa. Cảm ơn. – Oddthinking

0

rời khỏi a = và sử dụng các tác dụng phụ trên a:

[x.append('a') for x in a] 
print a 
+2

Xin vui lòng, không. Ném đi một danh sách hiểu chỉ để sử dụng các tác dụng phụ của nó là hình thức xấu; đề xuất của bạn hoạt động, nhưng nó cau mày khi giống như cách sử dụng 'map' tương tự đã được cau mày. Rõ ràng là tốt hơn là ngầm; sử dụng vòng lặp thay vì đọc danh sách. – tzot

6

Như những người khác đã nói, append đột biến danh sách riêng của mình và bạn không nên gán nó vào một biến. Thực thi nó thay đổi dữ liệu của nó, cập nhật hiệu quả mọi người chỉ vào nó.

Nhưng, có một mẹo tôi sử dụng khi tôi muốn làm công cụ trong một * cách chức năng trong khi đột biến đối tượng hiện có (chứ không phải là xây dựng những cái mới, trong trường hợp này sử dụng a=[x + ['a'] for x in a], hay đặc biệt là x + ['a']).

Vì vậy, nếu bạn đang dũng cảm đủ bạn cũng có thể làm điều này:

>>> a=[[1,2],[3,4],[5,6]] 
>>> a=[x.append('a') or x for x in a] 
>>> a 
[[1, 2, 'a'], [3, 4, 'a'], [5, 6, 'a']] 

này hoạt động vì lợi nhuận appendNoneor tiếp tục trên để tìm kiếm một giá trị thật-y, mà x (đó là list với ít nhất những gì được thêm vào nó).

Tại sao tôi thậm chí cần điều này?

Giả sử bạn có một danh sách và bạn muốn chèn một số thành viên của nó vào một danh sách mới, và cập nhật các tài liệu tham khảo phù hợp:

Vì vậy, bạn có danh sách all:

>>> all = [[], [], [], []] 

Một số nó được chèn vào và cập nhật vào một danh sách mới x:

>>> x = [i.append('x') or i for i in all[:2]] 
>>> x 
[['x'], ['x']] 

một số all cũng được chèn vào và u pdated vào một danh sách y:

>>> y = [i.append('y') or i for i in all[1:3]] 

all được cập nhật:

>>> all 
[['x'], ['x', 'y'], ['y'], []] 

Nhưng x cũng được cập nhật:

>>> x 
[['x'], ['x', 'y']] 

y được tạo ra như mong đợi:

>>> y 
[['x', 'y'], ['y']] 

Nhìn chung, đối với các tác vụ đơn giản, tôi khuyên bạn nên sử dụng vòng lặp for cập nhật một cách rõ ràng. Đây là những gì được coi là pythonic.

Về mặt kỹ thuật, nếu bạn có quyền truy cập vào các lớp danh sách, bạn có thể làm điều này một chức năng:

def more_functional_append(self, x): 
    self.append(x) 
    return self 
  • functional programming được dựa trên tất cả các tuyên bố làm cơ bản một điều, và không có tác dụng phụ (như vậy , không đột biến và trả lại). append không phải là rất chức năng vì nó biến đổi một danh sách (lập trình hàm thuần túy chỉ có các đối tượng bất biến) và không trả lại kết quả để chuyển cho các hành động khác (hàm). Sử dụng các khái niệm lập trình chức năng, bạn có thể tạo ra một lớp lớn tuyệt vời mà không ai có thể đọc được, còn được gọi là "bảo mật công việc" hoặc "mã xấu".
+0

Tôi có một cái nhìn khác về câu trả lời này ngày nay vì vậy nếu bạn đang đọc này xin vui lòng bình luận để tôi có thể cập nhật nó. Có một tính năng cốt lõi thiếu cho lập trình chức năng ở đây là bất biến và tôi nên mở rộng trên đó. –

1

Bạn có thể sử dụng bổ sung danh sách trong vòng một hiểu danh sách, như vậy:

a = [x + [ 'a'] cho x trong a]

này cung cấp cho các mong muốn kết quả cho a. Người ta có thể làm cho nó hiệu quả hơn trong trường hợp này bằng cách gán ['a'] cho một tên biến trước vòng lặp, nhưng nó phụ thuộc vào những gì bạn muốn làm.

0

Trong lần gán giá trị đầu tiên của danh sách của bạn, hãy hiểu một lỗi thuộc tính, đối tượng 'NoneType' không có thuộc tính 'append', giúp giải thích tại sao danh sách của bạn, a, sẽ được tải với Không có (s). Để bàn điều khiển của tôi ném lỗi, tôi đã sử dụng x làm biến cho danh sách hiểu và cũng như trình lặp.

Traceback (most recent call last): 
x = [x.append('a') for x in a] 
AttributeError: 'NoneType' object has no attribute 'append' 

Sau đó, tôi hoàn nguyên về cho x và nó đã ném cùng một lỗi.

Traceback (most recent call last): 
a = [x.append('a') for x in a] 
AttributeError: 'NoneType' object has no attribute 'append' 
Các vấn đề liên quan