Fast Efficient way to transfer an object to another list
Steven D'Aprano
steve at REMOVE-THIS-cybersource.com.au
Fri Apr 30 23:35:49 EDT 2010
On Fri, 30 Apr 2010 19:16:04 -0700, Jimbo wrote:
> Hello I have a relatively simple thing to do; move an object from one to
> list into another. But I think my solution maybe inefficient & slow. Is
> there a faster better way to move my stock object from one list to
> another? (IE, without having to use a dictionary instead of a list or is
> that my only solution?)
If you already know which object needs to be moved, it is easy:
>>> fruits = ["apple", "banana", "carrot", "orange", "pear"]
>>> vegetables = ["potato", "lettuce", "onion"]
>>>
>>> # move carrot from fruits to vegetables
...
>>> vegetables.append("carrot")
>>> fruits.remove("carrot")
>>>
>>> print fruits
['apple', 'banana', 'orange', 'pear']
>>> print vegetables
['potato', 'lettuce', 'onion', 'carrot']
The only tricky thing is if you don't know which object needs to be
moved. The way to solve that depends on what you need to do -- is there
only one object that might need to be moved, or could there be more than
one? How do you recognise it? There are many solutions. Here's one:
>>> even_numbers = []
>>> odd_numbers = odd_numbers = [1, 9, 8, 6, 2, 7, 3, 0, 4, 5]
>>> for i in range(len(odd_numbers)-1, -1, -1):
... n = odd_numbers[i]
... if n % 2 == 0: # even?
... even_numbers.append(n)
... del odd_numbers[i]
...
>>> even_numbers
[4, 0, 2, 6, 8]
>>> odd_numbers
[1, 9, 7, 3, 5]
Can you see why I iterated over the list backwards? Why didn't I just do
this?
for i, n in enumerate(odd_numbers):
if n % 2 == 0: # even?
even_numbers.append(n)
del odd_numbers[i]
You can re-write this more efficiently by using Python built-ins. First
you need to recognise what it is doing: first it searches for the item
with the stock code, then it appends it to the new list, then it deletes
it from the old list.
> def transfer_stock(stock_code, old_list, new_list):
> """ Transfer a stock from one list to another """
> # is there a more efficient & faster way to
> index = 0
> for stock in old_list:
> temp_stock = stock
> if temp_stock.code == stock_code:
> new_list.append(temp_stock)
> del old_list[index]
> index += 1
> return new_list
If you know there is one, and only one, item with that stock code:
def transfer_stock(stock_code, old_list, new_list):
""" Transfer a stock from one list to another """
i = old_list.index(stock_code) # search
new_list.append(old_list[i]) # copy
del old_list[i] # delete
return new_list
However, this will fail to work correctly if you have more than one
identical stock codes that all need to be moved, or if there are none. So
here's a version that handles both cases:
def transfer_stock(stock_code, old_list, new_list):
""" Transfer a stock from one list to another """
while True: # loop forever
try:
i = old_list.index(stock_code)
except ValueError:
# not found, so we're done
break
new_list.append(old_list[i])
del old_list[i]
return new_list
--
Steven
More information about the Python-list
mailing list