1

I have a list of tuples that contain a float, and two custom objects:

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

I then have a line of code that appends tuples to that:

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

I am trying to figure out a clean way to add the following kind of line:

If newTuple[0] (the float number) is > than any of the 2nd largest tuple float numbers, append it. Otherwise no. Any idea how to do that element-wise boolean on a tuple list?

EDIT - sorry, I meant to add the 2nd largest part.

Thanks- KC

7
  • is your list sorted according to the numbers? And 2nd largest means that (13,xx) qualifies, but (11,xx) doesn't, right? Commented Feb 28, 2017 at 20:00
  • What is your code to find the second largest element of ExampleList? Commented Feb 28, 2017 at 20:00
  • Not sure if I understood you correctly. Did you want to add newTuple, if newTuple[0] is larger than any of the existing counterparts in ExampleList? Commented Feb 28, 2017 at 20:01
  • sorted(ExampleList)[-2][0] represents the second largest Commented Feb 28, 2017 at 20:04
  • @Jean-FrançoisFabre - yes, its sorted according to the numbers. I'm running a large loop that is meant to only record the top 5 'results' (aka the float above) Commented Feb 28, 2017 at 20:04

3 Answers 3

2

Here's the cleanest way to do it (that I am aware of):

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

Although If you're looking for efficiency, look at @Jean-François Fabre 's answer

Sign up to request clarification or add additional context in comments.

1 Comment

thanks but the efficiency of my method is yet to be proven. Your method is OK. It allocates more memory, but if the sort operation is faster, maybe it's worth.
1

max is ruled out here, since we need the 2nd best value. sort would work but it allocates the full sorted list in return, only to discard most of the values.

A nice way of getting the 2nd largest float is to use heapq.nlargest in a generator comprehension (better check that input list has at least 2 elements in the general case, though)

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)

7 Comments

I like the solution, but I think that's a bit complicated for a small personal program
Heap will take nlogn in construction which is same as any efficient sort such as quicksort.
You can use heapq._heapify_max(sampleList) to have a heap that is max to min.
why the nasty _ before the name? Means it's not recommended to use it internally right?
@hashcode55 thanks. Also if the list is big, it may be nice not to allocate a big sorted list to discard most of the elements.
|
0

Since your list is already sorted, I would look at the bisect module to find the sorted insertion point. Then just calculate if that insertion meets the criteria.

Example:

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' 

Testing:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.