YardenST
YardenST

Reputation: 5256

python - move some items on a list to the end

I would like to perform the following action most efficiently :

Lets say we have this list:

items = ['a','c','d','e','f','s'] #items are unique (can be a set, but its a list so items are ordered)
special_items = ['e','a']

The result should be to convert items to be:

items = ['c','d','f','s','e','a'] # e,a now at the end

My current solution is:

items = [item for item in items if item not in special_items] #remove special items
items.extend(special_items) #add them to the end of the list

It works fine, but not very efficient i believe.

Upvotes: 0

Views: 529

Answers (1)

parchment
parchment

Reputation: 4002

First, you can use itertools.chain to join two sequences. Never mind, see edit below.

If you don't need the ordering in items, you can subtract one set from another:

sitems = set(items)
sspecial = set(special_items)
print(list(itertools.chain(sitems - sspecial, 
                           special_items)))
# ['c', 's', 'f', 'd', 'e', 'a']

If you need the ordering and special_items is large, you can get a boost by converting special_items into a set first:

sspecial = set(special_items)
list(itertools.chain((x for x in items if x not in sspecial),
                     special_items))

Edit: turns out itertools.chain is not as fast as I thought.

%timeit list(itertools.chain((x for x in rdata if x not in rset), rlist))
10000 loops, best of 3: 111 µs per loop

%timeit [x for x in rdata if x not in rset] + rlist
10000 loops, best of 3: 79.2 µs per loop

So do convert special_items into a set, don't use itertools.chain. (Unless I made a mistake in my testing)

Upvotes: 3

Related Questions