Fast Efficient way to transfer an object to another list
Bryan
bryanjugglercryptographer at yahoo.com
Sun May 2 21:52:06 EDT 2010
Steven D'Aprano wrote:
> The simplest way to speed the above code up is not to start from the
> beginning each time. That requires two very small changes. And since
> deletions from the front of the list are slow, MRAB's suggestion is also
> a good idea.
Those two speed-ups provide worst-case linear run-time, but as MRAB
astutely noted, his optimization assumes that order is unimportant.
That's a bad assumption for a general extract-from-list function.
Where order does not matter, I'd suspect 'list' was a poor choice of
data type. Here's a general, order-preserving, linear-time version:
def extract(lst, predicate):
""" Return items of lst satisfying predicate, deleting them from
lst.
"""
result = []
j = 0
for i in range(len(lst)):
if predicate(lst[i]):
result.append(lst[i])
else:
lst[j] = lst[i]
j += 1
del lst[j:]
return result
# some testing:
for nitems in range(10):
for pred in [lambda x: True,
lambda x: False,
lambda x: x % 2 == 0,
lambda x: x % 2 == 1,
lambda x: x < nitems // 2,
lambda x: x >= nitems // 2]:
original = list(range(nitems))
source = original[:]
extracted = extract(source, pred)
assert len(source) + len(extracted) == nitems
assert sorted(source) == source
for n in source:
assert not pred(n)
assert n in original
assert sorted(extracted) == extracted
for n in extracted:
assert pred(n)
assert n in original
--
--Bryan
More information about the Python-list
mailing list