【问题标题】:Python - query over list of tuplesPython - 查询元组列表
【发布时间】:2017-03-01 04:43:15
【问题描述】:

我有一个包含浮点数和两个自定义对象的元组列表:

ExampleList = [(10.5, Obj1, Obj2), (11.5, Obj1, Obj2), (14., Obj1, Obj2)]

然后我有一行代码将元组附加到该代码:

newTuple = (15,Obj1, Obj2)    
ExampleList.append(newTuple)

我正在尝试找出一种干净的方法来添加以下类型的行:

如果 newTuple[0](浮点数)大于任何第二大元组浮点数,则追加它。否则没有。知道如何在元组列表上执行按元素的布尔运算吗?

编辑 - 抱歉,我的意思是添加第二大部分。

谢谢-KC

【问题讨论】:

  • 您的列表是按数字排序的吗?第二大意味着(13,xx) 符合条件,但(11,xx) 不符合条件,对吧?
  • 找到ExampleList的第二大元素的代码是什么?
  • 不确定我是否理解正确。如果 newTuple[0] 大于 ExampleList 中的任何现有对应项,是否要添加 newTuple?
  • sorted(ExampleList)[-2][0]代表第二大
  • @Jean-FrançoisFabre - 是的,它是根据数字排序的。我正在运行一个大循环,仅记录前 5 个“结果”(也就是上面的浮点数)

标签: python


【解决方案1】:

这是最干净的方法(我知道):

secondLargest = sorted(ExampleList)[-2][0]
if (newTuple[0] > secondLargest):
    ExampleList.append(newTuple)

虽然如果您正在寻找效率,请查看@Jean-François Fabre 的答案

【讨论】:

  • 谢谢,但我的方法的效率还有待证明。你的方法没问题。它分配了更多内存,但如果sort 操作更快,也许值得。
【解决方案2】:

max 在这里被排除,因为我们需要第二好的值。 sort 会起作用,但它会分配完整的排序列表作为回报,只是丢弃大部分值。

获得第二大浮点数的一个好方法是在生成器理解中使用heapq.nlargest(不过,最好检查输入列表在一般情况下至少有 2 个元素)

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)

【讨论】:

  • 我喜欢这个解决方案,但我认为这对于一个小型个人程序来说有点复杂
  • 堆在构造中将采用 nlogn,这与任何高效排序(如快速排序)相同。
  • 您可以使用heapq._heapify_max(sampleList) 拥有一个从最大值到最小值的堆。
  • 为什么名字前有讨厌的_?意思是不建议在内部使用吧?
  • @hashcode55 谢谢。此外,如果列表很大,最好不要分配一个大的排序列表来丢弃大部分元素。
【解决方案3】:

由于您的列表已经排序,我会查看bisect 模块以找到排序后的插入点。然后只需计算该插入是否符合标准。

例子:

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')]

【讨论】:

    猜你喜欢
    • 2017-02-03
    • 1970-01-01
    • 2022-01-06
    • 2011-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多