Reputation: 2889
I have a list of column names, name_columns
. The list contains a subset of special column names, as well as non-special column names. The special column names are stored in the list special_columns
. I want to sort name_columns
so that the special column names appear first in the sorted list, in the order they are listed in special_columns
.
The order of the non-special column names is really not that important, as long as they appear after the special columns.
Example
special_columns = ['from_date', 'to_date', 'id_1', 'id_2', 'id_3', 'id_4']
name_columns = ['a', 'id_2', 'from_date', 'to_date', 'id_4', 'c']
#Do some smart sorting
#After sorting
name_columns = ['from_date', 'to_date', 'id_2', 'id_4', 'a', 'c']
I have mulitple list's like name_columns
and they all contain various subset (including none) of special_columns
.
Any suggestions on how this can be achieved?
Upvotes: 1
Views: 1927
Reputation: 12679
In one line you try :
special_columns = ['from_date', 'to_date', 'id_1', 'id_2', 'id_3', 'id_4']
name_columns = ['a', 'id_2', 'from_date', 'to_date', 'id_4', 'c']
new=[]
final=[[new.append(item),name_columns.remove(item)] for item in special_columns if item in name_columns]
new.extend(name_columns)
print(new)
Detailed solution:
ordered=[]
for item in special_columns:
if item in name_columns:
ordered.append(item)
name_columns.remove(item)
ordered.extend(name_columns)
print(ordered)
output:
['from_date', 'to_date', 'id_2', 'id_4', 'a', 'c']
Upvotes: 1
Reputation: 55479
One way to do this is to create a dict that contains the order info of the special items. Creating a dict beforehand is much more efficient than calling the .index
method on every item that you want to sort. The trick is to assign zero to the non-special items, and negative numbers to the special items, and then sort in reverse, so that the non-special items will always come at the end of the sorted list.
special_columns = ['from_date', 'to_date', 'id_1', 'id_2', 'id_3', 'id_4']
name_columns = ['a', 'id_2', 'from_date', 'to_date', 'id_4', 'c']
special_order = {u: i for i, u in enumerate(reversed(special_columns), 1)}
name_columns.sort(key=lambda s: special_order.get(s, 0), reverse=True)
print(name_columns)
output
['from_date', 'to_date', 'id_2', 'id_4', 'a', 'c']
Upvotes: 1
Reputation: 15204
How about like this:
special_columns = ['from_date', 'to_date', 'id_1', 'id_2', 'id_3', 'id_4']
name_columns = ['a', 'id_2', 'from_date', 'to_date', 'id_4', 'c']
temp2 = set(name_columns).difference(special_columns)
sorted_cols = [a for a in special_columns if a in name_columns] + sorted(list(temp2))
# \_____________________1________________________/ \_______2_________/
print(sorted_cols) # ['from_date', 'to_date', 'id_2', 'id_4', 'a', 'c']
Two parts to the answer:
List-comprehension
that loops thought the special
names and
stores them in the result if they exist in the name_column
.name_column
that are not
specialFew remarks:
sorted()
call on list(temp2)
to speed up the code.temp2
is of course not required.Upvotes: 3
Reputation: 186
Do you need really to sort the list? You could just create a new "sorted" one and use it. Something like:
special_columns = ['from_date', 'to_date', 'id_1', 'id_2', 'id_3', 'id_4']
name_columns = ['a', 'id_2', 'from_date', 'to_date', 'id_4', 'c']
a = []
for el in name_columns:
if el in special_columns:
a.insert(0, el)#insert in the beggining of the resulting list
else:
a.append(el)
print a
['id_4', 'to_date', 'from_date', 'id_2', 'a', 'c']
Upvotes: 1
Reputation: 17506
Try using a key
function as an argument for sorted
:
>>> special_columns = ['from_date', 'to_date', 'id_1', 'id_2', 'id_3', 'id_4']
>>> name_columns = ['a', 'id_2', 'from_date', 'to_date', 'id_4', 'c']
>>> print(sorted(name_columns,key=lambda x: special_columns.index(x) if x in special_columns else 10e99))
['from_date', 'to_date', 'id_2', 'id_4', 'a', 'c']
Upvotes: 1