Reputation: 165
given
a = [1,4,5,3,2,6,0]
b = ['b','e','f','d','c','g','a']
order b
in place, the expected order of b
is available in the corresponding positional element of a
.
output will be
['a','b','c','d','e','f','g']
try for other similar input sets.
a = [4,0,1,3,2]
b = ['E','A','B','D','C']
I can get it done using a third list, even sorted()
creates a third list, but the key is to sort b
in place
print sorted(b,key=lambda bi : a[b.index(bi)])
core of the problem is how to prevent iterating over items in b
that were already iterated.
Upvotes: 0
Views: 128
Reputation: 13539
def sorter(a,b):
for i in range(len(a)):
while i != a[i]:
ai = a[i]
b[i], b[ai], a[i], a[ai] = b[ai], b[i], a[ai], a[i]
return b
Upvotes: 1
Reputation: 304137
The key is to realise that the items in b
aren't much use to the key function. You are interested in their counterparts in a
. To do this inplace, means you can't just use zip
to pair the items up. Here I use the default argument trick to get an iterator over a
into the lambda function.
>>> a = [1,4,5,3,2,6,0]
>>> b = ['b','e','f','d','c','g','a']
>>> b.sort(key=lambda x, it=iter(a): next(it))
>>> b
['a', 'b', 'c', 'd', 'e', 'f', 'g']
Upvotes: 5
Reputation: 59416
Try this:
zip(*sorted(zip(a, b)))[1]
Should give:
('a', 'b', 'c', 'd', 'e', 'f', 'g')
Since during sorting the b
itself appears to be empty (see my question about that), you can use that piece of code to do it in-place:
b.sort(key=lambda x, b=b[:]: a[b.index(x)])
This uses a copy of the b
to search in during sorting. This is certainly not very good for performance, so don't blame me ;-)
Upvotes: 6
Reputation: 12715
Simple bubble sort:
for i in range( len(a) ):
for j in range(len(a)-1-i):
if (a[j] > a[j+1]):
#swap a[j] & a[j+1]
#swap b[j] & b[j+1]
Upvotes: 0