0

I have a list like:

barcode = ["13350V1","13350V10","13350V2","13350V20"]

I want to sort this list based on the last three digits, so the result would be:

newbarcode = ["13350V1","13350V2","13350V10","13350V20"]

Now I am able to do this using the script below, but I am not exactly sure what does this mean (x: str(x)[-3]) and appreciate your help in this regard.

newbarcode = sorted(barcode, key=lambda x: str(x)[-3])
Corralien
  • 109,409
  • 8
  • 28
  • 52
  • 1
    Are you sure you want to sort for last 3 digits and not starting at V? – Thomas Weller Jan 10 '22 at 14:26
  • 1
    `[-3]` is one character only. You probably want `[-3:]` (note the colon) – Thomas Weller Jan 10 '22 at 14:27
  • https://stackoverflow.com/questions/37914387/python-sort-using-key-and-lambda-what-does-lambda-do might help, it discusses using key and lambda in python sorting. – joanis Jan 10 '22 at 14:29
  • @ThomasWeller I want to sort the list based on the last three digits to get a result of v1,v2,v10, v20, so yes you are correct. – Parya Khoshroo Jan 10 '22 at 14:30
  • @Corralien this will result in ["13350V10","13350V1","13350V20","13350V2"] – Parya Khoshroo Jan 10 '22 at 14:31
  • That's not a very good example. In the first two examples the most significant character is the 0 before V. In the last 2 examples because the number after V has two digits the sort uses V as the most significant character. Are you sure this is how you want to sort this SN? Or you want to sort by the digits after V? –  Jan 10 '22 at 14:32
  • @Parya. Check my answer, I think it's probably what you expect. – Corralien Jan 10 '22 at 14:34
  • @ThomasWeller [-3:] this will work but what does exactly mean? – Parya Khoshroo Jan 10 '22 at 14:57
  • I want to sort by digits after V actually, but the serial number I have is not 01, 02, ..., 10, 20. Instead, it is 1,2,...,10,20 – Parya Khoshroo Jan 10 '22 at 14:59
  • x[n] is indexing. It gives you 1 element of a sequence. x[n:m] is called slicing. It gives you elements n to m. if m is omitted, it will give you the elements from n to the end – Thomas Weller Jan 10 '22 at 15:27
  • See also: https://stackoverflow.com/questions/509211/understanding-slice-notation – Thomas Weller Jan 10 '22 at 15:27
  • @ThomasWeller so in case of this newbarcode = sorted(barcode, key=lambda x: int(x.split("V")[-1])) [-1] means the last digit? and also in case of newbarcode = sorted(barcode, key=lambda x: str(x)[-3:]) the last 3 digits? – Parya Khoshroo Jan 10 '22 at 15:31
  • Yes. The negative indexes are a bit surprising when you know other languages. – Thomas Weller Jan 10 '22 at 15:36

2 Answers2

1

Find the position of V in the string then sort on all digits after but pad them with 0 to have a natural sort:

barcode = ['13350V1','13350V10','13350V2','13350V20']
newbarcode = sorted(barcode, key=lambda x: x[x.rindex('V')+1:].zfill(5))
print(newbarcode)

# Output
['13350V1', '13350V2', '13350V10', '13350V20']

Update

What does str(x)[-3] meaning?

Suppose the number 1357900:

>>> n
1357900

# Convert number to string
>>> str(n)
'1357900'

# Now get the third character from the end (negative indexing)
>>> str(n)[-3]
'9'

# Slice the string from the third character from the end to end
>>> str(n)[-3:]
'900'
Corralien
  • 109,409
  • 8
  • 28
  • 52
  • Using `rindex` is better. – pppig Jan 10 '22 at 14:37
  • Thank you @Corralien what does str(x)[-3] meaning? – Parya Khoshroo Jan 10 '22 at 15:25
  • Thank you! So when I write this: newbarcode = sorted(barcode, key=lambda x: str(x)[-3:]) how will slice translate into sort? is this because of the sorted function? so the above script means to sort it based on the last 3 digits? Is this what it means? – Parya Khoshroo Jan 10 '22 at 16:05
  • @Parya. Exactly. The function create this list: `['0V1', 'V10', '0V2', 'V20']` and sort it in the lexicographical order. That's why I used a different function. – Corralien Jan 10 '22 at 16:11
  • `x[x.rindex('V')+1:].zfill(5))` create a list like this `['00001', '00010', '00002', '00020']` respect the natural order. – Corralien Jan 10 '22 at 16:16
0

For more complex tasks it might be better for you to understand if you create a method instead of a magic one line lambda:

def sortbyend(x: str) -> int:    
    pieces = x.split("V")
    last_piece = pieces[-1]
    number = int(last_piece)
    return number

barcode = ["13350V1","13350V2","13350V10","13350V20"]    
newbarcode = sorted(barcode, key=sort_by_end)
print(newbarcode)

That way you can understand and test and debug the function individually before it gets used in the key property.

Once you understood lambdas and are more familiar with them, you can convert it to a lambda:

newbarcode = sorted(barcode, key=lambda x: int(x.split("V")[-1]))
Thomas Weller
  • 55,411
  • 20
  • 125
  • 222