由于你说的成本是你可以使用的整数:
def neardup(items):
forbidden = set()
for elem in items:
key = elem['name'], elem['code'], int(elem['cost'])
if key not in forbidden:
yield elem
for diff in (-1,0,1): # add all keys invalidated by this
key = elem['name'], elem['code'], int(elem['cost'])-diff
forbidden.add(key)
这是一个不那么棘手的方式,r eally计算差异:
from collections import defaultdict
def neardup2(items):
# this is a mapping `(name, code) -> [cost1, cost2, ... ]`
forbidden = defaultdict(list)
for elem in items:
key = elem['name'], elem['code']
curcost = float(elem['cost'])
# a item is new if we never saw the key before
if (key not in forbidden or
# or if all the known costs differ by more than 2
all(abs(cost-curcost) >= 2 for cost in forbidden[key])):
yield elem
forbidden[key].append(curcost)
这两种解决方案都避免重新扫描每个项目的整个列表。毕竟,如果(name, code)
是平等的,成本才会变得有趣,因此您可以使用字典快速查找所有候选项。
虽然有更好的技术方法(尤其是Jochen的答案,它使用'yield'来减少大型列表中的内存使用量),但我更喜欢您的方法的可读性。 – Pranab 2011-04-17 20:59:23