是否有更好(更有效)的方法从元组中删除项目?

时间:2018-10-19 19:54:17

标签: python python-2.7

我有一个元组列表,从中删除了ith元素。现在,我正在使用以下方法:

map(lambda e: list(e)[:i] + list(e)[(i + 1):], data)

将元组转换为列表(两次!),然后切出元素。结果意味着我有列表而不是元组,但这很好。有没有一种更快的方法,可能是通过在单独的map操作中将每个元组转换为列表来实现的?

2 个答案:

答案 0 :(得分:6)

您根本不需要转换为列表。只是切片元组;切片不会改变元组,它会创建一个新对象:

map(lambda e: e[:i] + e[i:], data)

并不是上面的切片操作都有用,因为切片到i并从i切片会创建完全相同的元组。如果应省略i,则要在第二个切片的开头添加1:

map(lambda e: e[:i] + e[i + 1:], data)

演示:

>>> t = (41, 42, 45, 54, 81, 162)
>>> t[:3] + t[3:]  # same tuple again
(41, 42, 45, 54, 81, 162)
>>> t[:3] + t[4:]  # skip index 3
(41, 42, 45, 81, 162)

您可能想在这里重新考虑使用元组;元组实际上是为异构数据结构设计的;元组具有结构,列表具有顺序。参见What's the difference between lists and tuples?

答案 1 :(得分:3)

无需将其包装到列表中,您可以:

map(lambda e: (*e[:i], *e[i+1:]), data)

但是这些方法都将花费 O(mn)时间,其中<​​em> m 是元组的Arity,而 n 是元组的数量。 / p>

上面的代码还将处理 siceable 可迭代对象,因此本身不是元组。此外,结果始终是元组。例如,range(..)对象:

>>> i=3
>>> list(map(lambda e: (*e[:i], *e[i+1:]), [range(1,7)]))
[(1, 2, 3, 5, 6)]

这本身不是想要的行为。也可以使用e[:i] + e[i+1:],这将为range(..)对象引发错误。对于list,它将返回list。没有一个“固有的”更好的方法:它取决于用例。