Finding the insertion point in a list
Steven D'Aprano
steve at REMOVE.THIS.cybersource.com.au
Sat Mar 17 02:01:13 EDT 2007
On Fri, 16 Mar 2007 18:17:08 -0800, Paul Rubin wrote:
> tkpmep at hotmail.com writes:
>> Or with a generator comprehension
>> n = sum ( y>x[i] for i in range(len(x)) ) - 1
>>
>> But there has to be a cleaner way, as the first approach is unwieldy
>> and does not adapt to changing list lengths, and the second is not
>> obvious to a casual reader of the code.
>
> How about:
>
> n = len([y > t for t in x])
(1) It's wrong. That always returns the length of the list. Perhaps you
meant something like this?
len(["anything will do" for t in x if y > t])
or even
len(filter(lambda t, y=y: y>t, x))
(2) It's barely more comprehensible than the alternative that the Original
Poster rejected for being insufficiently clear.
Since (almost) everyone insists on ignoring the bisect module and
re-inventing the wheel, here's my wheel:
def find(alist, n):
"""Return the position where n should be inserted in a sorted list."""
if alist != sorted(alist):
raise ValueError('list must be sorted')
where = None
for i in range(len(alist)):
if where is not None:
break
alist.insert(i, n)
if alist == sorted(alist):
where = i
del alist[i]
if where is None:
where = len(alist)
return where
Here's another dodgy implementation:
def find(alist, n):
return sorted(alist + [n]).index(n)
It's especially good for large lists. Not!
--
Steven.
More information about the Python-list
mailing list