Python 3:从元组列表中删除空元组

3

我有一个元组列表,如下所示:

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

我希望您能将其翻译成以下内容:

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

我想从列表中删除空元组(),但同时保留元组('',)。我无法找到一种方法来从列表中删除这些空元组。
我尝试使用myList.remove(())和for循环来实现,但是要么不起作用,要么语法有误。希望能得到帮助。

1
需要注意的一点是,在布尔上下文中(例如,if my_tuple:),空元组 () 的值为 False。然而,只包含空/虚假值的元组(例如,('',)(None, ()))的值为 True - Max Noel
4个回答

10
您可以过滤“空”值:
filter(None, myList)

或者你可以使用列表推导式。在Python 3中,filter()返回一个生成器;列表推导式在Python 2或3中都返回一个列表:

[t for t in myList if t]

如果您的列表不仅包含元组,您可以显式地测试空元组:

如果您的列表不仅包含元组,您可以显式地测试空元组:

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

Python 2演示:

>>> 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',)]

在这些选项中,filter()函数是最快的:

>>> 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

在Python 3中,建议使用列表推导式代替:
>>> 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

list(filter(None, myList)) 有多快? - squiguy
1
@squiguy:在Python 3上,list(filter(None, myList))比列表推导式慢。请参见http://ideone.com/xWcqgh。 - Martijn Pieters
还有 itertools.ifilter,它可能会更快。 - Akavall
@Akavall:不,ifilter()在Python 3中已经不存在了,因为内置的filter()取代了它。在Python 2中,它与list(filter(...))版本一样慢。 - Martijn Pieters
@MartijnPieters 已完成!非常感谢 :) - ilikemustard
显示剩余2条评论

7
myList = [x for x in myList if x != ()]

这个完美地解决了问题!不知道为什么之前没有想到,但非常感谢。 - ilikemustard

3

使用列表推导式过滤掉空元组:

>>> 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',)]
>>>

这是因为空元组在Python中被评估为False

谢谢!这实际上是我在代码中使用的答案,因为它看起来最简洁。 - ilikemustard
@ilikemustard - 不用客气!但是,如果我的回答是你使用的那一个,请不要忘记接受它。接受答案可以让未来的人知道问题已经得到解答。 - user2555451
是的,好主意!我刚开始提问题,还在摸索中。虽然这个回答完美地回答了我的问题,但还有另一个更详细的答案,我认为它更有帮助,所以我接受了那个答案。抱歉让你失望了,非常感谢你的回答!祝你有美好的一天。 - ilikemustard
1
嘿,没关系。重要的是问题得到了回答。此外,我认为皮特的回答应该被采纳。他显然比我付出了更多的努力。 - user2555451

2

显式优于隐式

我认为通过清晰地指定过滤器的功能,这个更易读且不含歧义。因此,我们明确地想要移除那些空元组,即()

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))

也许最好不要将它们转换为列表,而是使用生成器。在决定使用哪种方法时,请参阅此问题。详情请见此处

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接