Python-对元组列表的查询
我有一个包含浮点的元组列表和两个自定义对象:Python-对元组列表的查询,python,Python,我有一个包含浮点的元组列表和两个自定义对象: ExampleList = [(10.5, Obj1, Obj2), (11.5, Obj1, Obj2), (14., Obj1, Obj2)] 然后我有一行代码将元组附加到: newTuple = (15,Obj1, Obj2) ExampleList.append(newTuple) 我正试图找出一种干净的方法来添加以下类型的行: 如果newTuple[0](浮点数)大于任何第二大元组浮点数,请附加它。否则不会。你知道如何在元组列表
ExampleList = [(10.5, Obj1, Obj2), (11.5, Obj1, Obj2), (14., Obj1, Obj2)]
然后我有一行代码将元组附加到:
newTuple = (15,Obj1, Obj2)
ExampleList.append(newTuple)
我正试图找出一种干净的方法来添加以下类型的行:
如果newTuple[0](浮点数)大于任何第二大元组浮点数,请附加它。否则不会。你知道如何在元组列表上实现元素级布尔吗
编辑-抱歉,我想添加第二大部分
谢谢-KC以下是最干净的方法(我知道):
虽然如果你在寻找效率,看看@Jean-François Fabre的答案,这里排除了max,因为我们需要第二个最佳值
sort
可以工作,但它会分配完整的排序列表作为回报,只会丢弃大部分值
获得第二大浮点值的一个好方法是在生成器理解中使用heapq.nlargest
(不过最好检查输入列表在一般情况下至少有2个元素)
由于您的列表已经排序,我将查看模块以查找排序后的插入点。然后计算插入是否符合标准 例如:
import bisect
Obj1='o1'
Obj2='o2'
sample=[(10.5, Obj1, Obj2), (11.5, Obj1, Obj2), (14., Obj1, Obj2)] # needs to be sorted
newTuple = (13,Obj1, Obj2)
def my_insert(li, t):
ip=bisect.bisect_left(li, newTuple)
if len(li)-ip<2:
li.insert(ip, t)
else:
print t, 'not inserted'
你的名单是按数字排序的吗?第二大的意思是
(13,xx)
符合条件,但(11,xx)
不符合条件,对吗?您的代码是什么,可以找到示例列表的第二大元素?不确定我是否理解正确。如果newTuple[0]大于ExampleList中的任何现有副本,是否要添加newTuple?sorted(ExampleList)[-2][0]
表示第二个副本largest@Jean-弗朗索瓦-是的,它是根据数字排序的。我正在运行一个大循环,它只记录前5个“结果”(也就是上面的float),我喜欢这个解决方案,但我认为这有点复杂,因为一个小的个人程序heap将采用nlogn-in结构,这与快速排序等任何有效排序相同。你可以使用heapq.\u heapify\u max(sampleList)
要有一个从最大到最小的堆,为什么要在名称前面加上讨厌的\u
?表示不建议在内部使用它,对吗?@hashcode55谢谢。另外,如果列表很大,最好不要分配一个大的排序列表来丢弃大部分元素。谢谢,但是我的方法的效率还有待验证。你的方法还可以。它分配了更多的内存,但是如果sort
操作更快,那么它可能值得。
import heapq
Obj1 = object()
Obj2 = object()
sampleList = [(10.5, Obj1, Obj2), (11.5, Obj1, Obj2), (14., Obj1, Obj2)]
second_largest = heapq.nlargest(2,(x[0] for x in sampleList))[-1] # [14.0, 11.5]
newTuple = (15,Obj1, Obj2)
if newTuple[0]>second_largest:
sampleList.append(newTuple)
import bisect
Obj1='o1'
Obj2='o2'
sample=[(10.5, Obj1, Obj2), (11.5, Obj1, Obj2), (14., Obj1, Obj2)] # needs to be sorted
newTuple = (13,Obj1, Obj2)
def my_insert(li, t):
ip=bisect.bisect_left(li, newTuple)
if len(li)-ip<2:
li.insert(ip, t)
else:
print t, 'not inserted'
>>> my_insert(sample, newTuple); print sample
[(10.5, 'o1', 'o2'), (11.5, 'o1', 'o2'), (13, 'o1', 'o2'), (14.0, 'o1', 'o2')]
>>> my_insert(sample, newTuple); print sample
(13, 'o1', 'o2') not inserted
[(10.5, 'o1', 'o2'), (11.5, 'o1', 'o2'), (13, 'o1', 'o2'), (14.0, 'o1', 'o2')]