2012-10-01 27 views
10

Làm cách nào để xóa phần tử khỏi danh sách nếu nó khớp với chuỗi con?Xóa một mục khỏi danh sách khớp với chuỗi con - Python

Tôi đã cố gắng loại bỏ một phần tử từ một danh sách bằng cách sử dụng pop()enumerate phương pháp nhưng có vẻ như tôi đang thiếu một vài mặt hàng tiếp giáp mà cần phải được loại bỏ:

sents = ['@$\tthis sentences needs to be removed', 'this doesnt', 
    '@$\tthis sentences also needs to be removed', 
    '@$\tthis sentences must be removed', 'this shouldnt', 
    '# this needs to be removed', 'this isnt', 
    '# this must', 'this musnt'] 

for i, j in enumerate(sents): 
    if j[0:3] == "@$\t": 
    sents.pop(i) 
    continue 
    if j[0] == "#": 
    sents.pop(i) 

for i in sents: 
    print i 

Output:

this doesnt 
@$ this sentences must be removed 
this shouldnt 
this isnt 
#this should 
this musnt 

Đầu ra mong muốn:

this doesnt 
this shouldnt 
this isnt 
this musnt 
+3

Trường hợp cổ điển trong việc xóa các mục khỏi danh sách trong khi bạn đang lặp qua danh sách đó. Đọc hàng tá câu hỏi Stack Overflow khác liên quan đến điều này. Ngoài ra, hãy xem [ghi chú trong tài liệu] (http://docs.python.org/reference/compound_stmts.html#for). –

+1

bạn nên tránh thay đổi độ dài của vùng chứa trong khi lặp qua nó, đây là công thức cho thiên tai – wim

+0

Nói chung, thường tốt hơn là tạo danh sách lọc mới thay vì cố sửa đổi danh sách tại chỗ. Các thuật toán không thay đổi luôn luôn dễ dàng hơn để lý luận thông qua (mặc dù không phải lúc nào cũng dễ dàng hơn để tìm ra cách viết). Khi bạn chỉ thay thế các giá trị, đôi khi hiệu quả của việc làm việc tại chỗ, nhưng khi bạn đang xóa hoặc chèn vào giữa danh sách, bạn thường nhận được hiệu quả _worse_ cùng với logic ít mạnh mẽ hơn. – abarnert

Trả lời

20

Làm thế nào abo ut một cái gì đó đơn giản như:

>>> [x for x in sents if not x.startswith('@$\t') and not x.startswith('#')] 
['this doesnt', 'this shouldnt', 'this isnt', 'this musnt'] 
+0

ah một danh sách hiểu, thanh lịch! để tôi thử. – alvas

+0

+1 để có câu trả lời rõ ràng nhất. – abarnert

8

này nên làm việc:

[i for i in sents if not ('@$\t' in i or '#' in i)] 

Nếu bạn muốn chỉ những điều mà bắt đầu với những quy định sentential sử dụng phương pháp str.startswith(stringOfInterest)

+2

Tôi muốn tranh luận điều này là tốt hơn so với hai khác cho không giả định các chất nền là lúc bắt đầu – Frikster

9

Kỹ thuật khác sử dụng filter

filter(lambda s: not (s[0:3]=="@$\t" or s[0]=="#"), sents) 

Sự cố với sự chấp thuận orignal của bạn h là khi bạn đang ở trong mục danh sách i và xác định nó sẽ bị xóa, bạn xóa nó khỏi danh sách, sẽ trượt mục i+1 vào vị trí i. Lần lặp tiếp theo của vòng lặp bạn đang ở chỉ mục i+1 nhưng mục thực sự là i+2.

Có ý nghĩa?

+0

cảm ơn cho lời giải thích! popping một danh sách trong khi liệt kê là ngớ ngẩn thực sự. hahaha .. – alvas

+0

+1 để giải thích sự cố. – abarnert

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