Python Forum

Full Version: Sorting list of lists with string and int
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
So I'm trying to solve this exercise: https://open.kattis.com/problems/cups

Although the problem is simple and does not require much work I'd like to improve my code because it looks pretty bad:

#!/usr/bin/python3

n = int(input())

a = [input().split() for i in range(n)]

for i in a:
    if(i[0].isdigit()):
        i[0] = int(i[0])/2
        i[1], i[0] = i[0], i[1]
    elif(i[1].isdigit()):
        i[1] = int(i[1])

a.sort(key=lambda x: x[1])
[print(i[0]) for i in a]
The main concern is that I don't know if the string will be in a form int string or string int so I need to check for it.
You could use
for i in a:
    try:
        i[1] = int(i[1])
    except ValueError:
        i[0], i[1] = i[1], int(i[0]) / 2
Why do we need to be explicit and write except ValueError?
(May-06-2018, 11:42 AM)Otbredbaron Wrote: [ -> ]Why do we need to be explicit and write except ValueError?
I'm not sure I understand exactly what you mean, but here I know that if i[1] contains anything that is not convertible to an integer the call to int() will raise ValueError. In such a case, I always catch the exact exception because I don't want to catch anything else. For example if for some reason there is no i[1], python will throw KeyError and I don't want to catch this at this point. For debugging purposes, it is always better to let unexpected exceptions propagate.
actually, the easiest way would be to add sorted to your line 5 list comprehension

a = [sorted(input().split()) for i in range(n)]
this way you always get the number as element with index 0 because when sorting '0' to '9' always go before 'A'

def parse_data(item):
    return (int(item[0]), item[1])


data = ['red 10', '10 blue', 'green 7']
data = [parse_data(sorted(item.split())) for item in data]
output = [cup for radius, cup in sorted(data)]
print('\n'.join(output))
note that sample output in your assignment is NOT correct
(May-07-2018, 05:38 AM)buran Wrote: [ -> ]actually, the easiest way would be to add sorted to your line 5 list comprehension

a = [sorted(input().split()) for i in range(n)]
this way you always get the number as element with index 0 because when sorting '0' to '9' always go before 'A'

def parse_data(item):
    return (int(item[0]), item[1])


data = ['red 10', '10 blue', 'green 7']
data = [parse_data(sorted(item.split())) for item in data]
output = [cup for radius, cup in sorted(data)]
print('\n'.join(output))
note that sample output in your assignment is NOT correct

It is correct because if it's in the format number color, then number need to be divided by 2 so it will be 5.

(May-06-2018, 02:26 PM)Gribouillis Wrote: [ -> ]
(May-06-2018, 11:42 AM)Otbredbaron Wrote: [ -> ]Why do we need to be explicit and write except ValueError?
I'm not sure I understand exactly what you mean, but here I know that if i[1] contains anything that is not convertible to an integer the call to int() will raise ValueError. In such a case, I always catch the exact exception because I don't want to catch anything else. For example if for some reason there is no i[1], python will throw KeyError and I don't want to catch this at this point. For debugging purposes, it is always better to let unexpected exceptions propagate.

I see now, I need to get used to this try except thing.
(May-07-2018, 05:54 AM)Otbredbaron Wrote: [ -> ]if it's in the format number color, then number need to be divided by 2 so it will be 5.
sorry, didn't notice that - my mistake
def parse_data(item):
    try:
        return int(item[0])/2, item[1]
    except ValueError:
        return (int(item[1]), item[0])


data = ['red 10', '10 blue', 'green 7']
data = [parse_data(item.split()) for item in data]
output = sorted([cup for radius, cup in data])
print('\n'.join(output))
and if you are comfortable with
def parse_data(item):
    item = item.split()
    try:
        return int(item[0])/2, item[1]
    except ValueError:
        return (int(item[1]), item[0])


data = ['red 10', '10 blue', 'green 7']
print('\n'.join(sorted([cup for radius, cup in map(parse_data, data)])))