给出基本类Item
:
class Item(object):
def __init__(self, val):
self.val = val
此类的对象列表(项的数量可以大得多):
items = [ Item(0), Item(11), Item(25), Item(16), Item(31) ]
和函数compute
处理并返回一个值。
在使用属性compute
时,如何找到列表中两项,函数val
返回相同的值?如果未找到任何内容,则应引发异常。如果有两个以上的项目相匹配,则简单地返回其中任何两个项目。
例如,让我们定义compute
:
def compute( x ):
return x % 10
排除的配对为:(Item(11), Item(31))
。
答案 0 :(得分:1)
您可以检查结果值集的长度:
class Item(object):
def __init__(self, val):
self.val = val
def __repr__(self):
return f'Item({self.val})'
def compute(x):
return x%10
items = [ Item(0), Item(11), Item(25), Item(16), Item(31)]
c = list(map(lambda x:compute(x.val), items))
if len(set(c)) == len(c): #no two or more equal values exist in the list
raise Exception("All elements have unique computational results")
要查找具有相似计算结果的值,可以使用字典:
from collections import Counter
new_d = {i:compute(i.val) for i in items}
d = Counter(new_d.values())
multiple = [a for a, b in new_d.items() if d[b] > 1]
输出:
[Item(11), Item(31)]
一种用于查找是否存在多个具有相同计算值的对象的更有效的方法是使用any
,这需要对Counter
对象进行一次传递,而将set
与len
需要多次迭代:
if all(b == 1 for b in d.values()):
raise Exception("All elements have unique computational results")
答案 1 :(得分:0)
可以使用包含val_to_it
由计算的Item
键控的字典val
:
val_to_it = {}
for it in items:
computed_val = compute(it.val)
# Check if an Item in val_to_it has the same computed val
dict_it = val_to_it.get(computed_val)
if dict_it is None:
# If not, add it to val_to_it so it can be referred to
val_to_it[computed_val] = it
else:
# We found the two elements!
res = [dict_it, it]
break
else:
raise Exception( "Can't find two items" )
可以for
块进行重写以处理n
个元素:
for it in items:
computed_val = compute(it.val)
dict_lit = val_to_it.get(computed_val)
if dict_lit is None:
val_to_it[computed_val] = [it]
else:
dict_lit.append(it)
# Check if we have the expected number of elements
if len(dict_lit) == n:
# Found n elements!
res = dict_lit
break
答案 2 :(得分:0)
假设compute
返回的值是可散列的(例如float
值),则可以使用字典来存储结果。
您不需要做任何花哨的事情,例如存储所有产生结果的项目的multidict。一旦看到重复,就完成了。除了更简单之外,这还意味着我们在找到匹配项后就将搜索短路,甚至无需在其余元素上调用compute
。
def find_pair(items, compute):
results = {}
for item in items:
result = compute(item.val)
if result in results:
return results[result], item
results[result] = item
raise ValueError('No pair of items')