【问题标题】:Python 3: Removing an empty tuple from a list of tuplesPython 3:从元组列表中删除一个空元组
【发布时间】:2013-12-06 00:03:45
【问题描述】:

我有一个这样的元组列表:

>>>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 循环来执行此操作,但要么不起作用,要么我的语法错误。任何帮助将不胜感激。

【问题讨论】:

  • 需要注意的重要一点是,空元组 () 在布尔上下文中计算为 False(例如 if my_tuple:)。但是,仅包含空/假值(例如 ('',)(None, ()))的元组计算结果为 True

标签: python list tuples


【解决方案1】:

您可以过滤“空”值:

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: list(filter(None, myList)) 在 Python 3 上比列表理解慢。请参阅 ideone.com/xWcqgh
  • 还有itertools.ifilter可能会更快。
  • @Akavall: 不,ifilter() 在 Python 3 中不再存在,因为内置的 filter() 取代了它。在 Python 2 中,它与 list(filter(...)) 版本一样慢。
【解决方案2】:
myList = [x for x in myList if x != ()]

【讨论】:

  • 这非常有效!不知道我以前怎么没想到,但非常感谢。
【解决方案3】:

使用list comprehension 过滤掉空元组:

>>> 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 - 不客气!但是,如果我的答案是您使用的答案,那么请您不要忘记accept it。接受答案让未来的人知道问题已得到解答。
  • 好主意!我是提问的新手,所以我仍然掌握了窍门。虽然这个答案完美地回答了我的问题,但还有另一个更彻底的答案,我认为它更有帮助,所以我接受了。很抱歉让您失望了,非常感谢您的回答!祝你有美好的一天。
  • 嘿,没关系。重要的是问题得到了回答。此外,我什至认为彼得的回答值得接受。他显然比我付出了更多的努力。
【解决方案4】:

显式优于隐式

通过明确指定过滤器的功能,我发现这个更具可读性且不含糊。很明显我们想要删除那些空元组()

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

如果您不将它们转换为list 并将其用作generator,也许会很好。 在决定使用哪个时,请参阅此question

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-21
    • 2017-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多