2011-01-30 39 views
30

tôi có một danh sách với danh sách rỗng trong đó:Python: Cách xóa danh sách trống khỏi danh sách?

list1 = [[], [], [], [], [], 'text', 'text2', [], 'moreText'] 

Làm thế nào tôi có thể loại bỏ các danh mục sản phẩm nào để tôi nhận được:

list2 = ['text', 'text2', 'moreText'] 

tôi đã cố gắng list.remove ('') nhưng điều đó không 't làm việc.

+2

'''! = []', Đó là lý do tại sao '.remove' không hoạt động. Nhưng nó vẫn là một giải pháp tồi (hoặc bạn kiểm tra nếu có '[] trong list1' trước khi tay -' O (n ** 2) '- hoặc bắt lỗi nó ném khác - xấu xí). – delnan

+1

thật tuyệt vời khi bạn thấy rằng mặc dù câu hỏi của bạn không phổ biến, nhưng một người nào đó từ lâu đã đăng nó và nó đã được trả lời rất đẹp! Tôi yêu SO –

Trả lời

47

Hãy thử

list2 = [x for x in list1 if x != []] 

Nếu bạn muốn để có được thoát khỏi tất cả mọi thứ đó là "falsy", ví dụ chuỗi rỗng, các bộ trống, số không, bạn cũng có thể sử dụng

list2 = [x for x in list1 if x] 
+0

+1 để đề cập đến một cách khác để giải quyết vấn đề và cách nó khác biệt. – delnan

+0

Tôi biết điều này là cũ, nhưng tôi tiếp tục thấy rằng phương pháp cú đúp và tôi không thể tìm thấy bất cứ điều gì thông qua Google trên nó (Có lẽ vì Google không làm dấu chấm câu). Điều đó được gọi là gì để tôi có thể tìm hiểu thêm về những gì đang thực sự xảy ra ở đó? – David

+1

@David: [List comprehensions] (https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions) và [Generator expressions] (https://docs.python.org/3/tutorial /classes.html#generator-expressions). Ngoài ra còn có sự hiểu biết từ điển và thiết lập hiểu. –

0

Một vài lựa chọn: phiên

filter(lambda x: len(x) > 0, list1) # Doesn't work with number types 
filter(None, list1) # Filters out int(0) 
filter(lambda x: x==0 or x, list1) # Retains int(0) 

mẫu:

Python 2.7.1 (r271:86832, Nov 27 2010, 17:19:03) [MSC v.1500 64 bit (AMD64)] on 
win32 
Type "help", "copyright", "credits" or "license" for more information. 
>>> list1 = [[], [], [], [], [], 'text', 'text2', [], 'moreText'] 
>>> filter(lambda x: len(x) > 0, list1) 
['text', 'text2', 'moreText'] 
>>> list2 = [[], [], [], [], [], 'text', 'text2', [], 'moreText', 0.5, 1, -1, 0] 
>>> filter(lambda x: x==0 or x, list2) 
['text', 'text2', 'moreText', 0.5, 1, -1, 0] 
>>> filter(None, list2) 
['text', 'text2', 'moreText', 0.5, 1, -1] 
>>> 
+0

-1: 'len (x)> 0' về bản chất giống như' bool (x) 'hoặc chỉ' x'. – lunaryorn

+1

hoặc None cho 'filter()' –

+0

+1: @RC. Nếu bạn có các loại số trong danh sách của bạn, bạn không thể gọi len trên đó. Nếu bạn có một '0', nó sẽ được lọc ra bởi' None'. Nếu không, tôi thích câu trả lời này. –

3
>>> list1 = [[], [], [], [], [], 'text', 'text2', [], 'moreText'] 
>>> list2 = [e for e in list1 if e] 
>>> list2 
['text', 'text2', 'moreText'] 
+1

Ai đó có thể vui lòng chỉnh sửa điều này! Tôi dường như không nhận được các tùy chọn định dạng. – user225312

+0

được thực hiện (bạn cần sử dụng '{}') –

+0

@RC: Cảm ơn! Tôi biết điều đó, nhưng đối với một số lý do kỳ lạ nó không thể nhìn thấy (không có tùy chọn). – user225312

36

Bạn có thể sử dụng filter() thay vì một danh sách hiểu:

list2 = filter(None, list1) 

Nếu None được sử dụng làm đối số đầu tiên cho filter(), nó lọc ra mọi giá trị trong danh sách đã cho, là False trong ngữ cảnh boolean. Điều này bao gồm danh sách trống.

Nó có thể là hơi nhanh hơn so với danh sách hiểu, bởi vì nó chỉ thực hiện một chức năng duy nhất trong Python, phần còn lại được thực hiện trong C.

+0

lý do tại sao câu trả lời này không có nhiều upvotes và/hoặc là câu trả lời được chấp nhận? –

+0

@ MattO'Brien b/c nhiều lập trình viên Python tránh 'filter()', cũng như 'lambda',' map() ', và' reduce() '; điều này bao gồm [Guido mình] (http://www.artima.com/weblogs/viewpost.jsp?thread=98196), mặc dù bài viết đó là một chút cũ. Tôi có xu hướng thích hiểu danh sách b/c rõ ràng thường quan trọng hơn so với tăng tốc nhẹ với các phương thức này và toán tử 'lambda'. Điều đó đang được nói, trường hợp này là tầm thường b/c nó rất rõ ràng ý định của lập trình viên là gì. – BoltzmannBrain

5

Calling filter với None sẽ lọc ra tất cả các giá trị falsey từ danh sách (mà một danh sách trống là)

list2 = filter(None, list1) 
1

Tôi đã tìm thấy câu hỏi này vì tôi muốn làm giống như OP. Tôi muốn thêm các quan sát sau:

Cách lặp đi lặp lại (user225312, Sven Marnach):

list2 = [x for x in list1 if x] 

sẽ trả về một đối tượng list trong python3python2. Thay vào đó, cách lọc (lunaryorn, Imran) khác nhau sẽ cư xử trên phiên bản:

list2 = filter(None, list1) 

Nó sẽ trả về một đối tượng filter trong python3list trong python2 (xem this question tìm thấy cùng một lúc). Đây là một sự khác biệt nhỏ nhưng nó phải được đưa vào tài khoản khi phát triển các kịch bản tương thích.

Điều này không đưa ra bất kỳ giả thiết nào về hiệu suất của các giải pháp đó. Dù sao đối tượng bộ lọc có thể được hoàn nguyên về danh sách bằng cách sử dụng:

list3 = list(list2) 
0

Tôi cần lọc các mục trống từ các đối tượng lồng nhau phức tạp hơn. Tôi đã thực hiện một hàm đệ quy để làm điều đó. Xem my SO answer here.

0
a = [[1,'aa',3,12,'a','b','c','s'],[],[],[1,'aa',7,80,'d','g','f',''],[9,None,11,12,13,14,15,'k']] 

b=[] 
for lng in range(len(a)): 
     if(len(a[lng])>=1):b.append(a[lng]) 
a=b 
print(a) 

[[1, 'aa', 3,12, 'a', 'b', 'c', 's'], [1, 'aa', 7 , 80, 'd', 'g', 'f', ''], [9, Không, 11,12,13,14,15, 'k']]

-1
list1 = [[], [], [], [], [], 'text', 'text2', [], 'moreText'] 
list2 = [] 
for item in list1: 
    if item!=[]: 
     list2.append(item) 
print(list2) 

đầu ra:

['text', 'text2', 'moreText'] 
+0

Mã chỉ câu trả lời không phải là rất hữu ích của riêng mình. Nó sẽ giúp ích nếu bạn có thể thêm một số chi tiết giải thích cách thức/tại sao nó trả lời câu hỏi. Điều đó nói rằng, tôi không chắc chắn câu trả lời này cho biết thêm bất kỳ giá trị nào so với tất cả những người khác đối với câu hỏi năm tuổi này. – SiHa

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