2

I have a list labelled Data which I want to order in the following way:

Key order = 'ID', 'GE','FN','LN','MN','EM', 'ST'

Data = ['ID:123 GE:m FN:Amir LN:Maleki EM:[email protected] MN:0400101010  ST:VIC']

I managed to order it while it is in a dictionary like this:

d= {'ID':123, 'GE':'m', 'FN':'Amir', 'LN':'Maleki', 'MN':'0400101010', 'EM':'[email protected]', 'ST':'VIC'}

keyorder = ['ID', 'GE','FN','LN','MN','EM', 'ST']

final = sorted(d.items(), key=lambda i:keyorder.index(i[0]))

print(final)

[('ID', 123), ('GE', 'm'), ('FN', 'Amir'), ('LN', 'Maleki'), ('MN', '0400101010'), ('EM', '[email protected]'), ('ST', 'VIC')]

but can I do this without making the list into a dict. If not how do i turn the list to a dict? Thank you!!

4
  • 4
    and what do you want your end-result to look like? Will it be a string? A list? A what? Commented Jan 16, 2018 at 13:33
  • Well you need some way to map which key corresponds with what value. Commented Jan 16, 2018 at 13:34
  • 1
    answered here stackoverflow.com/questions/12814667/… Commented Jan 16, 2018 at 13:41
  • Is that really a list though, Data in his first message seems to be a string to be parsed. Commented Jan 16, 2018 at 13:47

3 Answers 3

4

First of all, make your keyorder a dict because list.index is an O(n) operation you don't want to perform for every comparison the sorting algorithm does.

>>> keyorder = 'ID', 'GE','FN','LN','MN','EM', 'ST'
>>> keyorder = dict(zip(keyorder, range(len(keyorder))))
>>> 
>>> keyorder
{'FN': 2, 'GE': 1, 'ID': 0, 'LN': 3, 'ST': 6, 'EM': 5, 'MN': 4}

Now you can sort by splitting the part before the : from each of your strings and get the corresponding priority from keyorder.

>>> data = ['ID:123 GE:m FN:Amir LN:Maleki EM:[email protected] MN:0400101010  ST:VIC']
>>> data = data[0].split()
>>> sorted(data, key=lambda x: keyorder[x.split(':', 1)[0]])
['ID:123', 'GE:m', 'FN:Amir', 'LN:Maleki', 'MN:0400101010', 'EM:[email protected]', 'ST:VIC']

(The first two lines here sanitize your Data list because it's just a list of one element containing a string.)

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

2 Comments

Maybe better yet like keyorder.get(x.split(':', 1)[0], 99999999)? There might be contents in the string for which order is not important or so..
@Ev.Kounis better float('inf') or float('-inf') as the fallback value if unknown prefixes can occur.
2

You can used sorted with key. It allows you to specify an arbitrary lambda expression to sort your data:

key_order = ['ID', 'GE','FN','LN','MN','EM', 'ST']
data = ['ID:12,3', 'GE:m', 'FN:Amir', 'LN:Maleki', 'EM:[email protected]', 'MN:0400101010',  'ST:VIC']
print(sorted(data, key=lambda x: key_order.index(x.split(':')[0]))) 

This gives as output:

['ID:12,3', 'GE:m', 'FN:Amir', 'LN:Maleki', 'MN:0400101010', 'EM:[email protected]', 'ST:VIC']

1 Comment

Thank you so much I realised that I don't need to put it in a dictionary to order it. But I have to display the final result as follows ID:153 GE:m FN:John LN:Liu MN:040181010 EM:[email protected] ST:NSW
0

Try something like this:

One line approach:

new_list=[0]*len(d)
[new_list.__setitem__(i,"{}:{}".format(j,d.get(j))) for i,j in enumerate(keyorder) if j in d]

print(new_list)

output:

['ID:123', 'GE:m', 'FN:Amir', 'LN:Maleki', 'MN:0400101010', 'EM:[email protected]', 'ST:VIC']

Detailed approach:

 d= {'ID':123, 'GE':'m', 'FN':'Amir', 'LN':'Maleki', 'MN':'0400101010', 'EM':'[email protected]', 'ST':'VIC'}

keyorder = ['ID', 'GE','FN','LN','MN','EM', 'ST']

new_list=[0]*len(d)

for i,j in enumerate(keyorder):
    if j in d:
        new_list[i]="{}:{}".format(j,d.get(j))

print(new_list)

output:

['ID:123', 'GE:m', 'FN:Amir', 'LN:Maleki', 'MN:0400101010', 'EM:[email protected]', 'ST:VIC']

2 Comments

Hi this is great but i need to display it like this ---> ID:153 GE:m FN:John LN:Liu MN:040181010 EM:[email protected] ST:NSW
@SakiVandanaDisanayake Your name is long string ;) just kidding , Check my updated solution. And if you like my solution then don't mark it accepted , Just use it ;)

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.