2012-04-24 37 views
27

Tôi muốn sử dụng toán tử gán trong danh sách hiểu. Làm thế nào tôi có thể làm điều đó?Làm cách nào để tôi có thể thực hiện các bài tập trong danh sách hiểu?

Mã sau là cú pháp không hợp lệ. Ý tôi là để thiết lập lst[0] đến một chuỗi rỗng '' nếu nó phù hợp với pattern:

[ lst[0] = '' for pattern in start_pattern if lst[0] == pattern ] 

Cảm ơn!

+3

Tôi nghĩ rằng bạn có điều này bên trong ... – dawg

+4

Điều này không rõ ràng. Đó là một dấu hiệu cảnh báo ngay lập tức. –

Trả lời

20

Có vẻ như bạn đang bối rối list comprehension với looping constructs bằng Python.

Danh sách hiểu được sản xuất - danh sách! Nó không cho chính nó vào một nhiệm vụ duy nhất trong một danh sách hiện có. (Mặc dù bạn có thể tra tấn cú pháp để làm điều đó ...)

Mặc dù nó không rõ ràng những gì bạn đang cố làm từ mã của bạn, tôi nghĩ nó giống với vòng lặp hơn danh sách (kiểm soát luồng) vs sản xuất một danh sách (danh sách hiểu)

Vòng qua danh sách như thế này:

for pattern in patterns: 
    if lst[0] == pattern: lst[0]='' 

Đó là một cách hợp lý để làm điều này, và là những gì bạn sẽ làm gì trong C, Pascal, vv Nhưng bạn cũng có thể chỉ cần kiểm tra danh sách cho một giá trị và thay đổi nó:

if lst[0] in patterns: lst[0] = '' 

Hoặc, nếu bạn không biết chỉ số:

i=lst.index[pattern] 
lst[i]='' 

hoặc, nếu bạn có một danh sách liệt kê và muốn thay đổi mỗi phần tử đầu tiên của mỗi sublist:

for i, sublst in enumerate(lst): 
    if sublst[i][0] in patterns: sublist[i][0]='' 

vv, v.v.

Nếu bạn muốn áp dụng điều gì đó cho từng phần tử trong danh sách, bạn có thể xem bằng cách sử dụng danh sách hoặc bản đồ, hoặc một trong nhiều công cụ khác trong bộ công cụ Python.

Cá nhân, tôi thường có xu hướng sử dụng comprehensions danh sách hơn để tạo danh sách:

l=[[ x for x in range(5) ] for y in range(4)] #init a list of lists... 

Đó là tự nhiên hơn:

l=[] 
for i in range(4): 
    l.append([]) 
    for j in range(5): 
     l[i].append(j)  

Nhưng để sửa đổi mà cùng một danh sách của danh sách, mà là nhiều hơn có thể hiểu được?

này:

l=[['new value' if j==0 else l[i][j] for j in range(len(l[i]))] for i in range(len(l))] 

hay này:

for i,outter in enumerate(l): 
    l[i][0]='new value'    

YMMV

Here là một hướng dẫn tuyệt vời về điều này.

+3

Và điều này nên được viết là 'if lst [0] trong các mẫu: lst [0] = '''. –

+1

@Tim: Gửi câu trả lời đó! Tôi không thể tin rằng tôi đã đưa ra ba cách khác để làm điều đó mà không có một trong những rõ ràng ... ;-) – Cameron

+0

@Tim Pietzcker: rằng cách tôi sẽ viết nó, nhưng tôi đã muốn hiển thị (giải thích của tôi) rằng ông đã có điều này bên trong ... – dawg

4

Tóm lại: bạn không thích. Danh sách hiểu được để tạo danh sách, không sửa đổi danh sách hiện có. Nếu bạn muốn sửa đổi danh sách, hãy sử dụng vòng lặp for, vì đó là những gì họ đang sử dụng.

Cách Pythonic viết mã đó sẽ là một cái gì đó như:

for pattern in start_pattern: 
    if lst[0] == pattern: 
     lst[0] = '' 
     #the following assumes that pattern will never be '' 
     #if that's possible, you can ignore this bit 
     break 

Tuy nhiên, nếu bạn thực sự, thực sự muốn làm nhiệm vụ bên trong một, và không quan tâm mỗi lập trình viên Python đã từng giao dịch với bạn đang ghét nó cho tất cả cõi đời đời, có một vài chức năng mà bạn có thể sử dụng:

  • Nếu biến bạn muốn gán cho là một toàn cầu, sau đó bạn có thể làm

    globals().update(var=value) 
    
  • Nếu biến bạn muốn gán cho là một chuỗi có thể thay đổi hoặc một bản đồ (ví dụ như một danh sách hoặc một dict)

    list.__setitem__(index, value) 
    
+0

Thời gian ngắt luôn hợp lệ. Ngay cả khi có '''' trong dữ liệu, nó sẽ chỉ định 'lst [0]' được gán lại cùng một giá trị ... – Cameron

+0

Trừ khi lst là một kiểu chuỗi có thể thay đổi được khi quá trình gán phần tử bị quá tải để theo dõi số lần một giá trị đã cho được gán hoặc bất kỳ loại hành vi không chuẩn nào khác. –

+0

Hmm, điểm tốt. Tôi hy vọng đó là một sự xuất hiện rất hiếm, mặc dù :-) – Cameron

7

Các Python ngôn ngữ có khái niệm riêng biệt cho các biểu thức và câu lệnh.

Chuyển nhượng là tuyên bố ngay cả khi cú pháp đôi khi lừa bạn nghĩ đó là một biểu thức (ví dụ: a=b=99 hoạt động nhưng là trường hợp cú pháp đặc biệt và không có nghĩa là b=99 là một biểu thức như ví dụ trong C).

Việc hiểu danh sách thay vì biểu thức vì chúng trả về một giá trị, theo nghĩa vòng lặp chúng thực hiện là sự cố và điểm chính là danh sách được trả về.

Tuyên bố có thể chứa biểu thức nhưng biểu thức không thể chứa câu lệnh.

Tuy nhiên, danh sách điều chỉnh mục được chuyển đổi nội bộ thành cuộc gọi phương thức (để cho phép tạo đối tượng giống như danh sách) và cuộc gọi phương thức là biểu thức. Vì vậy, bạn có thể kỹ thuật sử dụng phân mục danh sách trong một biểu thức:

[ lst.__setitem__(0, '') for pattern in start_pattern if lst[0] == pattern ] 

này được tuy nhiên được coi là xấu vì nó làm hại khả năng đọc và làm thế nào dễ dàng là để đọc mã nguồn là Trọng tâm chính bằng ngôn ngữ Python. Bạn nên viết thay vì ví dụ ...

for pattern in start_pattern: 
    if lst[0] == pattern: 
     lst[0] = '' 

rằng bằng cách này nhờ vào các nhà điều hành in tương đương với thậm chí có thể đọc được nhiều sách

if lst[0] in start_pattern: 
    lst[0] = '' 

comprehensions được sử dụng cho giá trị trả về của họ và họ làm cho một vòng lặp nội bộ ... Nếu những gì bạn muốn là vòng lặp sau đó chỉ cần viết một vòng lặp ... ai sẽ đọc mã cố gắng để hiểu những gì nó sẽ đánh giá cao rất nhiều (và bất cứ ai bao gồm mình trong một vài tuần).

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