Given two strings, how do I assign the shorter string to one variable and the longer string to another

Given two strings, how do I assign the shorter string to one variable and the longer string to another



I am learning python and would like to know if there is a pythonic way of doing this. Of course I can do an


if len(a) > len(b) :
(x,y) = (b,a)



and so on. But this seems a bit verbose. Is there a more beautiful way to do this in python?






@user3483203 have to sort by length.

– Can't Tell
Sep 13 '18 at 8:41






If you're looking for a clever way you can sort, but your way now is perfectly fine

– user3483203
Sep 13 '18 at 8:41






@user3483203 but I would need the else and so on. Kinda verbose I think. And do you know why people are downvoting this like hell? :D

– Can't Tell
Sep 13 '18 at 8:42






@Can'tTell I think that the downvotes are a sort of "I think it's primarly opinion-based, but not worth a flag", even if I think it's an interesting question. BTW you actually have a positive score!

– Gsk
Sep 13 '18 at 9:01





6 Answers
6



Sorting seems a bit overkill. You can do it in one line just with if.


if


x,y = (a,b) if len(a) < len(b) else (b,a)






Thanks for the answer. To explain more, it was not the length that bothered me, but the verbosity of expressing something so simple.

– Can't Tell
Sep 13 '18 at 8:47






@MBo I did in the title. In the code I have not, but I have said 'and so on'. I was too lazy to write the else part

– Can't Tell
Sep 13 '18 at 8:48






OK, removing my comment. But author should be more careful :)

– MBo
Sep 13 '18 at 8:51


x = min(a, b, key=len)
y = max(a, b, key=len)



Repetition, but intention is clear.



Removed parentheses that makes tuples out of a and b since min and max takes in variable number of arguments.


a


b


min


max






using sort with multiple assignment would be better. You run the comparisons only once like that.

– Ev. Kounis
Sep 13 '18 at 8:54



sort






I think this is the most expressive way to do what is stated in the title. "Assign shorter to one and the longer to another". The mission here isn't to deal with more than 2 variables and it would make sense to do it in two steps.

– Frederik.L
Sep 13 '18 at 9:02







@Ev.Kounis I agree that sorting approach generalizes to larger collection more elegantly. Performance wise, not sure if there is going to be significant difference since collection is small. The accepted solution is essentially a special case of sorting 2 items and, depending on individual preferences, more readable. My intention was to offer an alternative.

– lightalchemist
Sep 13 '18 at 9:14



Found one way.


(x,y) = sorted([a,b], key = len)






I prefer your original way.

– khelwood
Sep 13 '18 at 8:41






Don't get caught up in one-linerness, your code is perfectly readable now

– user3483203
Sep 13 '18 at 8:43






@Can'tTell if the number of lines influence a beautiful code, you should define what you mean with beautiful

– Gsk
Sep 13 '18 at 8:44






@Gsk I did not mean that as a general rule, but the original didn't seem very python like to me. But if you look at khelwood's answer you will see what I meant.

– Can't Tell
Sep 13 '18 at 8:46






Have you measure the execution time?. using if taking less time than using sorted. (ie, 0.007247173540780684 while using if and 0.012815168972169048 while using sorted in my machine)

– Abdul Niyas P M
Sep 13 '18 at 8:54



if


sorted


0.007247173540780684


if


0.012815168972169048


sorted



You can use sequence unpacking with min / max. This is still O(n) complexity, albeit a 2-pass solution, which doesn't involve creating an intermediary list or tuple of strings.


min


max


list


tuple


a = 'hello'
b = 'test'

x, y = (func(a, b, key=len) for func in (min, max))

print(x, y, sep='n')

# test
# hello



Here's a functional version:


from operator import methodcaller

x, y = map(methodcaller('__call__', a, b, key=len), (min, max))






A whole lot of pythonism here.

– Frederik.L
Sep 13 '18 at 9:13



Use min(n1, n2, n3, ...)


>>> n1 = "abcdefghijkl"
>>> n2 = "abc"
>>> min((n1,n2), key=len)
'abc'
>>> max((n1,n2), key=len)
'abcdefghijkl'






min('111', '0000') will return '0000'. This doesn't do what you think it does. You can however give len as a key to min

– user3483203
Sep 13 '18 at 8:42



min('111', '0000')


'0000'


len


min






@user3483203 Thanks just fixed!

– Jagjeet Singh
Sep 13 '18 at 8:52



The question seems really opinion-based, and for this reason I think we should define beautiful referring to the Zen of Python, in particular:



Flat is better than nested.

Sparse is better than dense.

Readability counts.



For these reasons, I think that your approach:


if len(a) > len(b) :
(x,y) = (b,a)
else:
(x,y) = (a,b)



is the best one.



Thanks for contributing an answer to Stack Overflow!



But avoid



To learn more, see our tips on writing great answers.



Required, but never shown



Required, but never shown




By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy