# Sorting two related lists

I have code that sorts two lists related with each other

"""
list1 reperesents customer
list2 reperesents amount of products they have brought
"""

list1=['a','c','e','i','o','u']
list2=[12,23,45,10,7,2]
list3=[]
for i in range(0,len(list1)):
list3.append([list1[i],list2[i]])
print list3
"""
[['a', 12], ['c', 23], ['e', 45], ['i', 10], ['o', 7], ['u', 2]]
"""
list3=sorted(list3,key=lambda x: list3[list3.index(x)][1])

print(list3)
"""
[['u', 2], ['o', 7], ['i', 10], ['a', 12], ['c', 23], ['e', 45]]
"""
for i in range(0.len(list3)):
list1[i]=list3[i][0]
list2[i]=list3[i][1]

print list1
print list2


List1 is the customers' names
List2 is the number of products each customer bought

So:

• 'a' bought 12 products
• 'c' bought 23 products

And so on.

Is there a better way to do this?

• You should ask review on actual code, not on anonymised code. (There's lots of room for improvement though) – Sjoerd Job Postmus Feb 5 '16 at 15:07
• posted code has an error (your second use of range() has 0.len instead of 0, len) – mcgyver5 Feb 5 '16 at 17:53

You should probably just change how the data is stored. You should have one list which contains all of a customers data. For instance, a dictionary that follows this template:

{"name": "a", "purchased": 12}


If you had a list of those, it would be trivial to sort them, using the list sorting functions.

customer_data = [
{"name": "a", "purchased": 12},
{"name": "c", "purchased": 23},
{"name": "o", "purchased": 7},
]
customer_data.sort(key=lambda customer: customer["purchased"])
print customer_data
# [{'name': '0', 'purchased': 7}, {'name': 'a', 'purchased': 12}, {'name': 'c', 'purchased': 23}]


Even though @SuperBiasedMan's answer makes a lot of sense and is the real solution, here's some things you can fix in your current approach.

First of all, do not use the """ ... """ syntax as comments. They're multiline strings. Instead, prefix each line using #. (Except when you mean it as a docstring, in which case you may use """ ... """ syntax).

"""
list1 reperesents customer
list2 reperesents amount of products they have brought
"""

list1=['a','c','e','i','o','u']
list2=[12,23,45,10,7,2]


First of all, the variable names do not make a lot of sense. list1 is customers, while list2 is a list of quantities. Better name them as such.

list3=[]
for i in range(0,len(list1)):
list3.append([list1[i],list2[i]])


Here you're doing a loop at the Python level. Faster and cleaner would be the following:

list3 = zip(list1, list2)


The difference will be that this gives a list of tuples instead of a list of lists. That's hardly going to be a problem in the following.

list3=sorted(list3,key=lambda x: list3[list3.index(x)][1])


Let's think out loud what the lambda does: first, we find out the position of x in list3. Then, we use that position to look up the value at the given position in list3, (which should, in all reality, just be x again), and then get the second component.

Better would be to write

list3 = sorted(list3, key=lambda x: x[1])


Or, even (which we can do because there are no other references to list3):

list3.sort(key=lambda x)


That's so much shorter!

for i in range(0.len(list3)):
list1[i]=list3[i][0]
list2[i]=list3[i][1]


Fixing the typo (. should be ,) is obvious.

for i in range(0, len(list3)):
list1[i]=list3[i][0]
list2[i]=list3[i][1]


Then, let's see if we can write this a bit differently. Yes we can!

list1, list2 = zip(*list3)


At this point, list1 and list2 are tuples. But that we can solve by writing

list1, list2 = map(list, zip(*list3))