views:

134

answers:

4

I have two lists: one contains a set of x points, the other contains y points. Python somehow manages to mix the x points up, or the user could. I'd need to sort them by lowest to highest, and move the y points to follow their x correspondants. They are in two separate lists.. how do I do it?

+7  A: 

You could zip the lists and sort the result. Sorting tuples should, by default, sort on the first member.

>>> xs = [3,2,1]
>>> ys = [1,2,3]
>>> points = zip(xs,ys)
>>> points
[(3, 1), (2, 2), (1, 3)]
>>> sorted(points)
[(1, 3), (2, 2), (3, 1)]

And then to unpack them again:

>>> sorted_points = sorted(points)
>>> new_xs = [point[0] for point in sorted_points]
>>> new_ys = [point[1] for point in sorted_points]
>>> new_xs
[1, 2, 3]
>>> new_ys
[3, 2, 1]
danben
thank you! that's awesome!
Gabriele Cirulli
Or, keep the points properly associated by not having two separate lists, but keeping the list of tuples.
Thomas Wouters
Read Mike Graham's answer. You can also use `zip` to unpack the tuples.
PreludeAndFugue
+4  A: 

If the x and the y are meant to be a single unit (such as a point), it would make more sense to store them as tuples rather than two separate lists.

Regardless, here's what you should do:

x = [4, 2, 5, 4, 5,…]
y = [4, 5, 2, 3, 1,…]

zipped_list = zip(x,y)
sorted_list = sorted(zipped_list)
BJ Homer
i would do that, but matplotlib uses lists like that
Gabriele Cirulli
+5  A: 
>>> xs = [5, 2, 1, 4, 6, 3]
>>> ys = [1, 2, 3, 4, 5, 6]
>>> xs, ys = zip(*sorted(zip(xs, ys)))
>>> xs
(1, 2, 3, 4, 5, 6)
>>> ys
(3, 2, 6, 4, 1, 5)
Mike Graham
You probably don't want to use `zip(*sorted(...))` if you have a large number of items. The argument-unpacking `*` can't do things as efficiently as `zip(xs, ys)`, as it has to pass as many arguments as you have tuples in the list.
Thomas Wouters
+1  A: 
>>> import numpy

>>> sorted_index = numpy.argsort(xs)
>>> xs = [xs[i] for i in sorted_index]
>>> ys = [ys[i] for i in sorted_index]

if you can work with numpy.array

>>> xs = numpy.array([3,2,1])
>>> xs = numpy.array([1,2,3])
>>> sorted_index = numpy.argsort(xs)
>>> xs = xs[sorted_index]
>>> ys = ys[sorted_index]
remosu