98

I have a list with empty lists in it:

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

How can I remove the empty lists so that I get:

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

I tried list.remove('') but that doesn't work.

Ian Mackinnon
  • 13,381
  • 13
  • 51
  • 67
SandyBr
  • 11,459
  • 10
  • 29
  • 27
  • 4
    `'' != []`, that's why `.remove` didn't work. But it's still a bad solution (either you check if there is `[] in list1` before hand - `O(n**2)` - or catch the error it throws otherwise - ugly). –  Jan 30 '11 at 12:53
  • 1
    so amazing when u found that although your question is not common, but someone long ago has posted it and it has been beautifully answered! I love SO – Sibbs Gambling Sep 05 '13 at 08:58

9 Answers9

165

Try

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

If you want to get rid of everything that is "falsy", e.g. empty strings, empty tuples, zeros, you could also use

list2 = [x for x in list1 if x]
Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
  • 5
    +1 for mentioning the other way that springs to mind and how it differs. –  Jan 30 '11 at 12:55
  • I know this is old, but I keep seeing that brace method and I can't find anything via Google on it (Probably because Google doesn't do punctuation). What is that called so I can learn more about what is really happening there? – David Jun 15 '14 at 06:41
  • 5
    @David: [List comprehensions](https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions) and [Generator expressions](https://docs.python.org/3/tutorial/classes.html#generator-expressions). There are also dictionary comprehensions and set comprehensions. – Sven Marnach Jun 16 '14 at 09:48
90

You can use filter() instead of a list comprehension:

list2 = filter(None, list1)

If None is used as first argument to filter(), it filters out every value in the given list, which is False in a boolean context. This includes empty lists.

It might be slightly faster than the list comprehension, because it only executes a single function in Python, the rest is done in C.

  • 1
    why doesn't this answer have more upvotes and / or be the accepted answer? – tumultous_rooster Mar 04 '15 at 21:36
  • 5
    @MattO'Brien b/c many Python programmers avoid `filter()`, as wells as `lambda`, `map()`, and `reduce()`; this includes [Guido himself](http://www.artima.com/weblogs/viewpost.jsp?thread=98196), although that post is a bit old. I tend to prefer list comprehensions b/c the clarity is often more important than the slight speedup with these methods and the `lambda` operator. That being said, this case is trivial b/c it's very clear what the programmer's intent is. – BoltzmannBrain Oct 06 '16 at 16:17
  • 21
    In Python3 I think this has to be amended to: list2 = list(filter(None, list1)). Just in case any newbies using Python3 wonder why this doesn't work for them :) – Shaken_not_stirred. Apr 24 '18 at 11:55
  • @Shaken_not_stirred. yaaaas. I am a newbie and I love SO. This response helped me avoid hours of hair-tearing! – Tonya Howe May 17 '22 at 16:19
10

Calling filter with None will filter out all falsey values from the list (which an empty list is)

list2 = filter(None, list1)
Imran
  • 87,203
  • 23
  • 98
  • 131
7
>>> list1 = [[], [], [], [], [], 'text', 'text2', [], 'moreText']
>>> list2 = [e for e in list1 if e]
>>> list2
['text', 'text2', 'moreText']
user225312
  • 126,773
  • 69
  • 172
  • 181
4

A few options:

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)

sample session:

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]
>>>
Bruno Bronosky
  • 66,273
  • 12
  • 162
  • 149
  • -1: `len(x) > 0` is essentially the same as `bool(x)` or just `x`. –  Jan 30 '11 at 13:06
  • +1: @RC. If you have number types in your list, you can't call len on it. If you have a `0`, it will be filtered out by `None`. Otherwise I like this answer. – Bruno Bronosky Mar 21 '15 at 21:52
2

I found this question because I wanted to do the same as the OP. I would like to add the following observation:

The iterative way (user225312, Sven Marnach):

list2 = [x for x in list1 if x]

Will return a list object in python3 and python2 . Instead the filter way (lunaryorn, Imran) will differently behave over versions:

list2 = filter(None, list1)

It will return a filter object in python3 and a list in python2 (see this question found at the same time). This is a slight difference but it must be take in account when developing compatible scripts.

This does not make any assumption about performances of those solutions. Anyway the filter object can be reverted to a list using:

list3 = list(list2)
Community
  • 1
  • 1
jlandercy
  • 7,183
  • 1
  • 39
  • 57
1
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)

Output:

[[1,'aa',3,12,'a','b','c','s'],[1,'aa',7,80,'d','g','f',''],[9,None,11,12,13,14,15,'k']]
Vineeth Sai
  • 3,389
  • 7
  • 23
  • 34
Arash.H
  • 101
  • 1
  • 9
  • You posted this in 2015; it has got zero points until it solved my problem in 2021. Lesson: keep rendering help. You do not know who your solution gets to benefit the most! Thanks. Plus one. – Omojola Micheal Mar 31 '21 at 09:43
1
list1 = [[], [], [], [], [], 'text', 'text2', [], 'moreText']
list2 = []
for item in list1:
    if item!=[]:
        list2.append(item)
print(list2)

output:

['text', 'text2', 'moreText']
pacholik
  • 8,607
  • 9
  • 43
  • 55
SUNITHA K
  • 150
  • 1
  • 3
  • 1
    Code only answers are not very useful on their own. It would help if you could add some detail explaining how/why it answers the question. That said, I'm not sure this answer adds any value over all the others to this five-year old question. – SiHa Sep 28 '16 at 11:44
0

Adding to the answers above, Say you have a list of lists of the form:

theList = [['a','b',' '],[''],[''],['d','e','f','g'],['']]

and you want to take out the empty entries from each list as well as the empty lists you can do:

theList = [x for x in theList if x != ['']] #remove empty lists
for i in range(len(theList)):
    theList[i] = list(filter(None, theList[i])) #remove empty entries from the lists

Your new list will look like

theList = [['a','b'],['d','e','f','g']]
Chidi
  • 901
  • 11
  • 15