Fast Efficient way to transfer an object to another list
Bryan
bryanjugglercryptographer at yahoo.com
Fri May 7 17:51:13 EDT 2010
Gabriel Genellina wrote:
> I'd do that in two steps:
>
> def transfer_stock(stock_code, old_list, new_list):
> # find the indexes to transfer
> indexes = [i for i,stock in enumerate(old_list)
> if stock.code==stock_code]
> # actually transfer them
> for index in reversed(indexes):
> stock = old_list[index]
> new_list.append(stock)
> del old_list[index]
> # I would not return anything
The first step -- finding the items -- looks great. The step of adding
items to new_list is just a bit squirly in that it reverse the order
they had in old_list. The last step -- deleting them from old_list --
is a sluggish order n**2 run-time; it can be done in order n. (That's
worst-case; your solution is linear time if either very few elements
get transferred or very few do not get transferred.)
Inspired by your use of list comprehension, and noting the simplicity
of the condition for transferring an item, I suggest the following
compact, order-preserving, linear-time solution:
def transfer_stock(stock_code, old_list, new_list):
new_list.extend(s for s in old_list if s.code==stock_code)
old_list[:] = [s for s in old_list if s.code!=stock_code]
#
# Even obviously-correct code deserves testing:
#
from random import choice
class Blurf:
def __init__(self, code):
self.code = code
for nitems in range(10):
for _ in range(17):
nl_prefix = choice(range(13))
new_list = [Blurf(3) for _ in range(nl_prefix)]
old_list = [Blurf(choice([3, 9])) for _ in range(nitems)]
nitems = len(new_list) + len(old_list)
original_new_list = new_list[:]
original_old_list = old_list[:]
transfer_stock(3, old_list, new_list)
assert len(old_list) + len(new_list) == nitems
for n in new_list:
assert n.code == 3
assert n in original_new_list or n in original_old_list
source = original_new_list + original_old_list
assert new_list == [s for s in source if s in new_list]
for n in old_list:
assert n.code != 3
assert n in original_new_list or n in original_old_list
assert old_list == [s for s in original_old_list
if s in old_list]
--
--Bryan
More information about the Python-list
mailing list