我在开发算法以确定n个元素列表的最小值时遇到了一些麻烦。找不到长度为n的数组的最小值并非如此,这很简单:
min = A[0]
for i in range(1, len(A)):
if min > A[i]: min = A[i]
print min
但我的清单包含对象:
class Object:
def __init__(self, somelist):
self.classification = somelist[0] # String
self.type = somelist[1] # String
self.first = somelist[2] # Integer
self.last = somelist[3] # Integer
对于相同的'分类|类型'对象我有m个元素,我想找到相同'分类|的最小元素通过比较第一个和最后一个之间的差异来输入。
示例:
obj1 = Object(['A', 'x', 4, 17])
obj2 = Object(['A', 'y', 5, 20])
obj3 = Object(['B', 'z', 10, 27])
obj4 = Object(['B', 'z', 2, 15])
obj5 = Object(['B', 'z', 20, 40])
obj6 = Object(['A', 'x', 6, 10])
obj7 = Object(['A', 'x', 2, 9])
list = [obj1, obj2, obj3, obj4, obj5, obj6, obj7]
所以我需要一个算法来确定列表的最小值:
A | x - >对象(['A','x',6,10])
B | z - >对象(['B','z',2,15])
A | y - >对象(['A','y',5,20])
谢谢!
答案 0 :(得分:7)
filtered = [obj for obj in lst if obj.classification == 'A' and obj.type = 'x']
min(filtered, key=lambda x: x.last - x.first)
注意:不要为变量list
命名:它内置阴影。
答案 1 :(得分:2)
这是一个简单易懂的动态程序方式:
class Object:
def __init__(self, somelist):
self.classification = somelist[0] # String
self.type = somelist[1] # String
self.first = somelist[2] # Integer
self.last = somelist[3] # Integer
def weight(self):
return self.last - self.first
def __str__(self):
return "Object(%r, %r, %r, %r)" % (self.classification, self.type, self.first, self.last)
__repr__ = __str__
obj1 = Object(['A', 'x', 4, 17])
obj2 = Object(['A', 'y', 5, 20])
obj3 = Object(['B', 'z', 10, 27])
obj4 = Object(['B', 'z', 2, 15])
obj5 = Object(['B', 'z', 20, 40])
obj6 = Object(['A', 'x', 6, 10])
obj7 = Object(['A', 'x', 2, 9])
olist = [obj1, obj2, obj3, obj4, obj5, obj6, obj7]
mindict = {}
for o in olist:
key = (o.classification, o.type)
if key in mindict:
if o.weight() >= mindict[key].weight():
continue
mindict[key] = o
from pprint import pprint
pprint(mindict)
这是输出:
{('A', 'x'): Object('A', 'x', 6, 10),
('A', 'y'): Object('A', 'y', 5, 20),
('B', 'z'): Object('B', 'z', 2, 15)}
注意:__str__
,__repr__
和pprint
内容只是为了获得精美的打印输出,这不是必需的。此外,上述代码在Python 2.2到2.7上保持不变。
运行时间:O(N)其中N是列表中的对象数。对对象进行排序的解决方案平均为O(N * log(N))。另一种解决方案似乎是O(K * N),其中K <= N是从对象导出的唯一(分类,类型)密钥的数量。
使用额外内存:仅限O(K)。其他解决方案似乎是O(N)。
答案 2 :(得分:1)
import itertools
group_func = lambda o: (o.classification, o.type)
map(lambda pair: (pair[0], min(pair[1], key=lambda o: o.last - o.first)),
itertools.groupby(sorted(l, key=group_func), group_func))
group_func
返回包含对象分类的元组键,然后键入(例如('A', 'x')
)。这首先用于对列表l
(sorted
调用)进行排序。然后,我们在排序列表上调用groupby
,使用group_func
分组到子列表中。每次密钥更改时,我们都会有一个新的子列表。与SQL不同,groupby要求列表在同一个键上预先排序。 map
获取groupby
函数的输出。对于每个组,map
返回一个元组。第一个元素是pair[0]
,它是键('A', 'x')
。第二个是由pair[1]
键确定的组的最小值(last - first
)。