[英]Remove namedtuple from list based on value
考虑下面的类,该类扩展了list
并追加了orderedtuple
:
from collections import namedtuple
Order = namedtuple('Order', ['id', 'value'])
class Orders(list):
def __init__(self, *args):
super(Orders, self).__init__()
self.extend(args)
def add(self, id, value):
self.append(Order(id, value))
...添加一些元素......
order = Orders()
order.add(1, 'alpha')
order.add(2, 'beta')
order.add(3, 'lambda')
order.add(4, 'omega')
......我们离开......
print order
[Order(id=1, value='alpha'), Order(id=2, value='beta'), Order(id=3, value='lambda'), Order(id=4, value='omega')]
假设我想通过它的id
删除任意元素。 例如:
order.remove(id=2) # ideal function call to remove by `id`
print order
[Order(id=1, value='alpha'), Order(id=3, value='lambda'), Order(id=4, value='omega')]
有一个相当简单的方法来实现这一目标吗?
您可以通过慢速方式进行操作:
def remove(self, id=None, value=None):
for elem in self:
if (id is not None and elem.id == id or
value is not None and elem.value == value):
super(Orders, self).remove(elem)
break
您可以向类中添加一个索引,以跟踪地图ID和/或值到特定索引,但在操作包含的订单列表时,您需要使该索引保持最新。 它看起来像这样:
def __init__(self, *args):
# ...
self._ids = {}
def append(self, id, value):
if id in ids:
raise ValueError('This order already exists!')
super(Orders, self).append(Order(id, value))
self._ids[id] = len(self) - 1
并且,如果您还调整了可以更改列表和更改订单等的所有其他方法,则可以通过其ID快速找到订单:
def remove(self, id):
if id not in self._ids
raise ValueError('No such order exists!')
del self[self._ids[id]]
[namedtuple for namedtuple in list if namedtuple.id != 'id']
您可以构建自定义remove
方法来为您执行此操作:
def remove(self, id):
for index, item in enumerate(self):
if item.id == id:
break
else:
raise ValueError("id not found")
del self[index]
演示:
>>> class Orders(list):
... def __init__(self, *args):
... super(Orders, self).__init__()
... self.extend(args)
... def add(self, id, value):
... self.append(Order(id, value))
... def remove(self, id):
... for index, item in enumerate(self):
... if item.id == id:
... break
... else:
... raise ValueError("id not found")
... del self[index]
...
>>> order = Orders()
>>> order.add(1, 'alpha')
>>> order.add(2, 'beta')
>>> order.add(3, 'lambda')
>>> order.add(4, 'omega')
>>> order
[Order(id=1, value='alpha'), Order(id=2, value='beta'), Order(id=3, value='lambda'), Order(id=4, value='omega')]
>>> order.remove(2)
>>> order
[Order(id=1, value='alpha'), Order(id=3, value='lambda'), Order(id=4, value='omega')]
>>> order.remove(5) # Nonexistent id
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 12, in remove
ValueError: id not found
>>>
请注意,该函数只对数据进行一次传递,就像普通的list.remove
。
该解决方案的主要优点是简单。 您可以在不更改类定义的任何其他部分的情况下实现remove
方法。 也就是说,它仍然以O(n)
复杂度运行。 如果性能是您主要关注的问题,那么您应该花时间实现@MartijnPieters提出的O(1)
id-lookup方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.