2

Assume I have two arrays, the first one containing int data, the second one containing positions

a = [11, 22, 44, 55]

b = [0, 1, 10, 11]

i.e. I want a[i] to be be moved to position b[i] for all i. If I haven't specified a position, then insert a -1

i.e

sorted_a = [11, 22,-1,-1,-1,-1,-1,-1,-1,-1, 44, 55]
            ^   ^                            ^   ^
            0   1                            10  11

Another example:

a = [int1, int2, int3]

b = [5, 3, 1]

sorted_a = [-1, int3, -1, int2, -1, int1]

Here's what I've tried:

def sort_array_by_second(a, b):

   sorted = []

   for e1 in a:
      sorted.appendAt(b[e1])

  return sorted

Which I've obviously messed up.

2
  • Both a and b are the same lenght aren't they? Commented Dec 12, 2013 at 0:11
  • Yes, they are always the same length. I'm using 0-based indexing, also Commented Dec 12, 2013 at 0:12

6 Answers 6

7

Something like this:

res = [-1]*(max(b)+1)   # create a list of required size with only -1's

for i, v in zip(b, a):
    res[i] = v 

The idea behind the algorithm:

  1. Create the resulting list with a size capable of holding up to the largest index in b
  2. Populate this list with -1
  3. Iterate through b elements
  4. Set elements in res[b[i]] with its proper value a[i]

This will leave the resulting list with -1 in every position other than the indexes contained in b, which will have their corresponding value of a.

Sign up to request clarification or add additional context in comments.

14 Comments

I think you are just mean to derive the ordering from b, the values don't matter
On second thoughts - maybe " I want a[i] to be be moved to position b[i] for all i " means you are right
I'm sorry I don't understand you quite well. The OP isn't very clear about the algorithm, I just tried to illustrate him one way to do it.
Hi, thanks for the quick response. I get a IndexError: tuple index out of range
|
1

I would use a custom key function as an argument to sort. This will sort the values according to the corresponding value in the other list:

to_be_sorted = ['int1', 'int2', 'int3', 'int4', 'int5']
sort_keys = [4, 5, 1, 2, 3]

sort_key_dict = dict(zip(to_be_sorted, sort_keys))

to_be_sorted.sort(key = lambda x: sort_key_dict[x])

This has the benefit of not counting on the values in sort_keys to be valid integer indexes, which is not a very stable thing to bank on.

Comments

1
>>> a = ["int1", "int2", "int3", "int4", "int5"]
>>> b = [4, 5, 1, 2, 3]
>>> sorted(a, key=lambda x, it=iter(sorted(b)): b.index(next(it)))
['int4', 'int5', 'int1', 'int2', 'int3']

Comments

1

Paulo Bu answer is the best pythonic way. If you want to stick with a function like yours:

def sort_array_by_second(a, b):
   sorted = []
   for n in b:
      sorted.append(a[n-1]) 
  return sorted

will do the trick.

Comments

1

Sorts A by the values of B:

A = ['int1', 'int2', 'int3', 'int4', 'int5']
B = [4, 5, 1, 2, 3]

from operator import itemgetter
C = [a for a, b in sorted(zip(A, B), key = itemgetter(1))]

print C

Output

['int3', 'int4', 'int5', 'int1', 'int2']

Comments

1
a = [11, 22, 44, 55] # values
b = [0, 1, 10, 11]  # indexes to sort by

sorted_a = [-1] * (max(b) + 1)
for index, value in zip(b, a):
    sorted_a[index] = value

print(sorted_a)
# -> [11, 22, -1, -1, -1, -1, -1, -1, -1, -1, 44, 55]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.