简体   繁体   中英

Python 3: Removing an empty tuple from a list of tuples

I have a list of tuples that reads as such:

>>>myList
[(), (), ('',), ('c', 'e'), ('ca', 'ea'), ('d',), ('do',), ('dog', 'ear', 'eat', 'cat', 'car'), ('dogs', 'cars', 'done', 'eats', 'cats', 'ears'), ('don',)]

And I would like it to read as such:

>>>myList
[('',), ('c', 'e'), ('ca', 'ea'), ('d',), ('do',), ('dog', 'ear', 'eat', 'cat', 'car'), ('dogs', 'cars', 'done', 'eats', 'cats', 'ears'), ('don',)]

ie I would like to remove the empty tuples () from the list. While doing this I want to preserve the tuple ('',) . I cannot seem to find a way to remove these empty tuples from the list.

I have tried myList.remove(()) and using a for loop to do it, but either that doesn't work or I am getting the syntax wrong. Any help would be appreciated.

You can filter 'empty' values:

filter(None, myList)

or you can use a list comprehension. On Python 3, filter() returns a generator; the list comprehension returns a list on either Python 2 or 3:

[t for t in myList if t]

If your list contains more than just tuples, you could test for empty tuples explicitly:

[t for t in myList if t != ()]

Python 2 demo:

>>> myList = [(), (), ('',), ('c', 'e'), ('ca', 'ea'), ('d',), ('do',), ('dog', 'ear', 'eat', 'cat', 'car'), ('dogs', 'cars', 'done', 'eats', 'cats', 'ears'), ('don',)]
>>> filter(None, myList)
[('',), ('c', 'e'), ('ca', 'ea'), ('d',), ('do',), ('dog', 'ear', 'eat', 'cat', 'car'), ('dogs', 'cars', 'done', 'eats', 'cats', 'ears'), ('don',)]
>>> [t for t in myList if t]
[('',), ('c', 'e'), ('ca', 'ea'), ('d',), ('do',), ('dog', 'ear', 'eat', 'cat', 'car'), ('dogs', 'cars', 'done', 'eats', 'cats', 'ears'), ('don',)]
>>> [t for t in myList if t != ()]
[('',), ('c', 'e'), ('ca', 'ea'), ('d',), ('do',), ('dog', 'ear', 'eat', 'cat', 'car'), ('dogs', 'cars', 'done', 'eats', 'cats', 'ears'), ('don',)]

Of these options, the filter() function is fastest:

>>> timeit.timeit('filter(None, myList)', 'from __main__ import myList')
0.637274980545044
>>> timeit.timeit('[t for t in myList if t]', 'from __main__ import myList')
1.243359088897705
>>> timeit.timeit('[t for t in myList if t != ()]', 'from __main__ import myList')
1.4746298789978027

On Python 3, stick to the list comprehension instead:

>>> timeit.timeit('list(filter(None, myList))', 'from __main__ import myList')
1.5365421772003174
>>> timeit.timeit('[t for t in myList if t]', 'from __main__ import myList')
1.29734206199646
myList = [x for x in myList if x != ()]

Use a list comprehension to filter out the empty tuples:

>>> myList = [(), (), ('',), ('c', 'e'), ('ca', 'ea'), ('d',), ('do',), ('dog', 'ear', 'eat', 'cat', 'car'), ('dogs', 'cars', 'done', 'eats', 'cats', 'ears'), ('don',)]
>>> myList = [x for x in myList if x]
>>> myList
[('',), ('c', 'e'), ('ca', 'ea'), ('d',), ('do',), ('dog', 'ear', 'eat', 'cat', 'car'), ('dogs', 'cars', 'done', 'eats', 'cats', 'ears'), ('don',)]
>>>

This works because empty tuples evaluate to False in Python.

Explicit is better than implicit

I find this one is more readable and not ambiguous by specifying clearly what function of the filter is. So clearly we want to remove those empty tuple which is () .

def filter_empty_tuple(my_tuple_list):
    return filter(lambda x: x != (), my_tuple_list)

# convert to list
def filter_empty_tuple_to_list(my_tuple_list):
    return list(filter(lambda x: x != (), my_tuple_list))

Perhaps it would be good if you don't convert them into a list and use it as generator . See this question when deciding which to use

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM