0

I have a list called all_of_the_data. this list contains 4 lists, list 1 = index 0 is Listings (str), list 2 = index 1 is Prices (str later converted to float), list 3 = index 2 is Dates (str), and list 4 = index 3 is Distance (float).

I want to sort Distance, list 4/index 3, lowest value -> highest value, but I want the elements to of the other lists to move with the sorted values.

all_of_the_data = 0[Listing #1, Listing #2, ... ]
                  1[Price #1, ...]
                  2[Date #1, ...]
                  3[19.2, 3, 20.3, ...]

So if 19.2 is moved to a new index 'z' in its list during the sort, then Listing #1, Price #1 and Date #1 should move to that index 'z' in all of their respected lists

I tried just outright sorting Distance list, but that just ruins the relation of Distance to the other elements like Listing and Price

the expected result is when the sort of the Distance list, all_of_the_data[3], is finished, then the relation of the elements Listing, Price, and Dates to Distance should stay the same.

Diego Delgado
  • 155
  • 1
  • 15

6 Answers6

0

Consider zipping the lists together and then sorting by that key, then destructure if you have to

allTheDataByEntry = list(zip(list1, list2, list3, list4))
allTheDataByEntry.sort(key = lambda x: x[3])
sortedList1 = [x[0] for x in allTheDataByEntry]
...
possum
  • 1,837
  • 3
  • 9
  • 18
0

You should consider to make use of dicts rather then four unrelated lists. What about putting all product information in a dict, make a list of dicts and then you can easily sort. For example:

all_of_the_data = [{'Listing': 1,
                   'Price': 20,
                   'Date': '10-2-2019',
                   'Distance': 10},
                   {'Listing': 2,
                    'Price': 5,
                    'Date': '15-2-2019',
                    'Distance': 2},
                   {'Listing': 3,
                    'Price': 30,
                    'Date': '12-2-2019',
                    'Distance': 1},
]

all_of_the_data_sorted = sorted(all_of_the_data, key=lambda x: x['Distance'])

will result in

[{'Listing': 3, 'Price': 30, 'Date': '12-2-2019', 'Distance': 1}, {'Listing': 2, 'Price': 5, 'Date': '15-2-2019', 'Distance': 2}, {'Listing': 1, 'Price': 20, 'Date': '10-2-2019', 'Distance': 10}]

Working with data sets like this, you may want to have a look at Pandas module and data frames.

and if you wonder how to convert the lists to dicts in the all_of_the_data list you can use something as below:

from pprint import pprint

listing = [1, 2, 3]
price = [20, 5, 30]
dates = ['10-2-2019', '15-2-2019', '12-2-2019']
distance = [10, 2, 1]

all_of_the_data = []
for i in range(len(listing)):
    content = {}
    content['Listing'] = listing[i]
    content['Price'] = price[i]
    content['Dates'] = dates[i]
    content['Distance'] = distance[i]
    all_of_the_data.append(content)

all_of_the_data.sort(key=lambda x: x['Distance'])
pprint(all_of_the_data)
Bruno Vermeulen
  • 2,970
  • 2
  • 15
  • 29
0

Try manually doing sorting of list [19.2, 3, 20.3, ...] and while changing positions of indexes of this list also change indexes of other lists too. Edit: This can be achieved in if block like this:

#all_code
if float(all_of_the_data[3][i])<float(all_of_the_data[3][i+1]):
        all_of_the_data[0][i],all_of_the_data[0][i+1]=all_of_the_data[0][i+1],all_of_the_data[0][i]
        all_of_the_data[1][i],all_of_the_data[1][i+1]=all_of_the_data[1][i+1],all_of_the_data[1][i]
        all_of_the_data[2][i],all_of_the_data[2][i+1]=all_of_the_data[2][i+1],all_of_the_data[2][i]
        all_of_the_data[3][i],all_of_the_data[3][i+1]=all_of_the_data[3][i+1],all_of_the_data[3][i]
#continue_code
Rizwan Amjad
  • 329
  • 4
  • 11
0

One option is to sort a list of possible indices by the values in the list you want to sort by. This then gives you the indices of the list that will sort the list. You can then re-use those indices on other lists if wanted. Similar to this answer. So if bar contains items, and foo contains some measurement over bar:

foo = [687, 225, 365,]
bar = ["mars", "venus", "earth"]
foo_sorting_indices = sorted(range(len(foo)), key = lambda i: foo[i])
foo_sorted = [foo[i] for i in foo_sorting_indices]
# [225, 365, 687]

bar_sorted_by_foo = [bar[i] for i in foo_sorting_indices]
# ["venus", "earth", "mars"]
Him
  • 5,257
  • 3
  • 26
  • 83
0

Use zip with sequence unpacking, twice:

Sample data:

all_of_the_data = [['A',    'Z',   'M',   'C',   'O'],
                   [ 1 ,     2 ,    3 ,    4 ,    5 ],
                   ['1/1', '2/2', '3/3', '4,4', '5/5'],
                   [19.2,    3,    20.3,   99,   45]]

Code:

sorted_data = list(zip(*sorted(zip(*all_of_the_data), key=lambda t:t[0])))

Output:

[('A', 'C', 'M', 'O', 'Z'),
 (1, 4, 3, 5, 2),
 ('1/1', '4,4', '3/3', '5/5', '2/2'),
 (19.2, 99, 20.3, 45, 3)]

How it works

zip(*seq) is an python idiom for doing a sort of transpose on a list of lists. The *seq part unpacks the outer list. If

seq = [ [ 1, 2, 3 ], [ 'a', 'b', 'c' ] ]

then zip(*seq) it equivalent to:

zip( [ 1, 2, 3 ], [ 'a', 'b', 'c' ] )

See how the list inside of seq become the arguments for zip()?

Zip() returns a tuple with the first element of each argument, and then a tuple with the second element of each argument, and so on until one of them runs out. In Python 2, zip() returns a list of these tuples. In Python 3, it returns an iterator over the tuples. So,

list( zip( *seq ) )

returns

[ ( 1, 'a' ), ( 2, 'b' ), ( 3, 'c' ) ]

The sorted( ... , key=lambda t:t[0]) sorts the list (or iterable) of tuples based on the first element ( the 'A, 'Z', 'M', ...).

The outer zip(* ... ) turns the now sorted list of tuples back into the 4 sequences that are now sorted according to the values in the first sequence. The list(...) is needed in Python 3 to turn the iterator into a list. Note that zip() returns tuples so the final result is a list of 4 tuples. If you really need a list of lists then add this line:

sorted_data = [list(seq) for seq in sorted_data]
RootTwo
  • 4,288
  • 1
  • 11
  • 15
0

Could I convert those 4 lists into a dictionary and sort by distance key/value pair?

Diego Delgado
  • 155
  • 1
  • 15