#๐Ÿ”’ sort list of tuples containing only strs by float (inside strs)

164 messages ยท Page 1 of 1 (latest)

twin pollen
#

hey, as the title said, I want to sort a list of tuples from largest to small:
[("something", "1.1"), ("something else", "5.5")]
but I dont even know how to approach this...
here's the code so far:

def sort_prices(list_of_tuples):
    """The function receives a list of tuples that each have an item and a price.
    :param list_of_tuples: a list of tuples.
    :type list_of_tuples: list
    :return: a list of tuples sorted by the price of the items in them from the largest to the smallest.
    :rtype: list
    """
    list_of_tuples = list_of_tuples.sort(reverse=True)
    return list_of_tuples

def main():
    # Call the function sort_prices
    products = [('milk', '5.5'), ('candy', '2.5'), ('bread', '9.0')]
    sort_prices(products)
    print(products)
    
if __name__ == "__main__":
    main()
echo gustBOT
#

@twin pollen

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

twin pollen
#

note that for reasons, the float must be inside strs

red flume
#

the .sort and sorted functions have an optional key argument that you'll want to use here

twin pollen
#

do I create a func for the key?

red flume
#

it should be an argument that takes an element e, and return the value you want to compare it by

twin pollen
#

or is there one already that exists for this type

red flume
#

!e e.g.

def my_cmp(e):
    return int(e[1])

items = ['x5', 'y4', 'z3']
print(list(sorted(items, key=my_cmp)))
echo gustBOT
#

@red flume :white_check_mark: Your 3.12 eval job has completed with return code 0.

['z3', 'y4', 'x5']
red flume
#

just imagine that what happens when deciding, say, whether 'x5' or 'y4' should go first, the function compares the values my_cmp('x5') and my_cmp('y4') to do so
so, it compares int('x5'[1]) and int('y4'[1]), which is 5 and 4 respectively. 4 comes before 5, so in the end 'y4' comes before 'x5'

twin pollen
#

im sorry, gimme a moment to understand

#

OOOH

#

yeah makes a lot of sense now

red flume
#

then just specify .sort(key=that_function) or sorted(..., key=that_function) then you're good to go

twin pollen
#

which would be

return float(e[1])
#

just noticed yeah

#

thank you ! let me try that real quick

red flume
#

!e

def my_cmp(e):
    return float(e[1])
items = [('milk', '5.5'), ('candy', '2.5'), ('bread', '9.0')]
print(list(sorted(items, key=my_cmp)))
echo gustBOT
#

@red flume :white_check_mark: Your 3.12 eval job has completed with return code 0.

[('candy', '2.5'), ('milk', '5.5'), ('bread', '9.0')]
red flume
#

you can also make use of lambdas if you know them

items = [('milk', '5.5'), ('candy', '2.5'), ('bread', '9.0')]
print(list(sorted(items, key=lambda e: float(e[1]))))
```the benefit is you won't have a random `my_cmp` name floating around when you really only use it once
twin pollen
#

ill def check lambda for future use

#

but for this assignment I think I needed to create a key

red flume
twin pollen
#

let me guess, lambda is just to not create a random func

#

yeahh

#

much more useful

red flume
#

they're called "anonymous functions," or unnamed functions, which is what their name implies
you can still do something = lambda ... but that kinda defeats the purpose and you might as well just do def something(...): ...

twin pollen
#

true

#

btw is there a way to reverse what im doing ???

#

from smallest to biggest

red flume
#

same key, reverse=True should do the trick

twin pollen
#

oooh thats good

#

so you can use 2 keys

#

or is it 1 key and 1 reverse

worn pulsar
red flume
# twin pollen so you can use 2 keys

well no, you specify the key function, which is how you're going to compare the elements, and reverse=False | True, which is whether it should sort ascending or descending

worn pulsar
twin pollen
#

I see

#

is there any other types like reverse?

red flume
#

wdym by "types"?
key and reverse are "arguments" (specifically, keyword arguments) of the function .sort() and sorted()

#

you can check the arguments by reading the docs, or say run help(...)

#

!e

print(help(sorted))
echo gustBOT
#

@red flume :white_check_mark: Your 3.12 eval job has completed with return code 0.

001 | Help on built-in function sorted in module builtins:
002 | 
003 | sorted(iterable, /, *, key=None, reverse=False)
004 |     Return a new list containing all items from the iterable in ascending order.
005 | 
006 |     A custom key function can be supplied to customize the sort order, and the
007 |     reverse flag can be set to request the result in descending order.
008 | 
009 | None
twin pollen
#

I see so we only have 2 options, key (which is kind of an unlimited option) and reverse

#

actually 3

#

none

worn pulsar
#

simpliest example is sorting dictionary by the values, and not the keys

>>> d = {'a': 1, 'b': -3, 'c': 2, 'd': -10}
>>> sorted(d)
['a', 'b', 'c', 'd'] <-- default behavior will simply sort keys
>>> sorted(d, key=d.get)
['d', 'b', 'a', 'c'] <-- d.get gets the key value and sorts by the value {'d': -10, 'b': -3, 'a': 1, 'c': 2}
red flume
# twin pollen none

key=None means that if you don't specify a value, it defaults to None
that means sorted(my_list) is the same as sorted(my_list, key=None)
and the implementation of sorted() and .sort() says that if key=None, it just uses the original values to compare, e.g. 'x5' stays as 'x5'

twin pollen
#

ooh

#

so its not none but key=none

worn pulsar
worn pulsar
#
>>> d = {'a': 1, 'b': -3, 'c': 2, 'd': -10}
>>> sorted(d, reverse=True)
['d', 'c', 'b', 'a'] <-- keys go in the reverse order
>>> sorted(d, key=d.get, reverse=True)
['c', 'a', 'b', 'd'] <-- values go in the reverse order {'c': 2, 'a': 1, 'b': -3, 'd': -10}
worn pulsar
# twin pollen I see

if u remember the previous example i showed, when reverse=False it sorts from lowest to highest

twin pollen
#

its exactly what I am doing except you already chose the pos

twin pollen
# worn pulsar if u remember the previous example i showed, when `reverse=False` it sorts from...

yes so thats my final result :

def sort_key(key):
    return float(key[1])

def sort_prices(list_of_tuples):
    """The function receives a list of tuples that each have an item and a price.
    :param list_of_tuples: a list of tuples.
    :type list_of_tuples: list
    :return: a list of tuples sorted by the price of the items in them from the largest to the smallest.
    :rtype: list
    """
    print(sorted(list_of_tuples, key=sort_key, reverse=True))

def main():
    # Call the function sort_prices
    products = [('milk', '5.5'), ('candy', '2.5'), ('bread', '9.0')]
    sort_prices(products)
    
if __name__ == "__main__":
    main()
#

but for next use its gonna be :

def sort_prices(list_of_tuples):
    """The function receives a list of tuples that each have an item and a price.
    :param list_of_tuples: a list of tuples.
    :type list_of_tuples: list
    :return: a list of tuples sorted by the price of the items in them from the largest to the smallest.
    :rtype: list
    """
    print(sorted(list_of_tuples, key=lambda float(key[1]), reverse=True))

def main():
    # Call the function sort_prices
    products = [('milk', '5.5'), ('candy', '2.5'), ('bread', '9.0')]
    sort_prices(products)
    
if __name__ == "__main__":
    main()
red flume
# echo gust <@208918673178492929> :white_check_mark: Your 3.12 eval job has completed with r...

the / and * are special symbols you can ignore for now
but fyi they specify which arguments are positional only, keyword only, or both

def fn(a, /, b, c, *, d): ...
````a` is positional only, `b c` are both, `d` is keyword only
example
```py
fn(10, ...)    # ok
fn(a=10, ...)  # not ok, a is positional only
fn(10, 1, 1, ...)    # ok
fn(10, 1, c=5, ...)  # ok
fn(1, 2, 3, 4)   # not ok, d is keyword only
fn(1, 2, 3, d=4) # ok
twin pollen
#

hmmm

#

how would you use that

red flume
#

what that means for something like def sorted(iterable, /, *, key=None, reverse=False): is

my_list = [1, 2, 3, 4]
sorted(my_list)           # ok
sorted(iterable=my_list)  # not ok, iterable is positional only
sorted(my_list, lambda x: x)      # not ok
sorted(my_list, key=lambda x: x)  # ok
#

it basically only matters to the people who are going to be using your function
if you're starting out, those people probably just refer to you and you only, so it doesn't matter too much

twin pollen
#

I see

worn pulsar
#

so in your case it will be

lambda key: float(key[1])
red flume
twin pollen
#

so it would be:

#
def sort_prices(list_of_tuples):
    """The function receives a list of tuples that each have an item and a price.
    :param list_of_tuples: a list of tuples.
    :type list_of_tuples: list
    :return: a list of tuples sorted by the price of the items in them from the largest to the smallest.
    :rtype: list
    """
    print(sorted(list_of_tuples, lambda key: float(key[1]), reverse=True))

def main():
    # Call the function sort_prices
    products = [('milk', '5.5'), ('candy', '2.5'), ('bread', '9.0')]
    sort_prices(products)
    
if __name__ == "__main__":
    main()
worn pulsar
#

almost

red flume
#

lambda: ... would be def fn(): ...

twin pollen
#

ooooh

worn pulsar
#

basically...

lambda key: float(key[1])
# IS SAME AS:
def func(key):
    return float(key[1])
#

but, obviously, that lambda doesnt have a name like func below does

twin pollen
#

I mean, once you get it its pretty easy

#

def func param

#

lambda is def , key is func and then you put your param (or what you expect the return to be)

worn pulsar
#

also, thing about python, is that you can create a block without indentation:

def func(key): return float(key[1])

this would work just as fine

twin pollen
#

I see

worn pulsar
#

and thats basically why lambda works

twin pollen
#

less work

#

btw is there a way to return the result instead of a print ?

worn pulsar
#

return ? ๐Ÿ’€

#

you do print(sorted(list_of_tuples, lambda key: float(key[1]), reverse=True))

twin pollen
#
def sort_key(key):
    return float(key[1])

def sort_prices(list_of_tuples):
    """The function receives a list of tuples that each have an item and a price.
    :param list_of_tuples: a list of tuples.
    :type list_of_tuples: list
    :return: a list of tuples sorted by the price of the items in them from the largest to the smallest.
    :rtype: list
    """
    list_of_tuples = sorted(list_of_tuples, key=sort_key, reverse=True)
    return list_of_tuples
worn pulsar
#

yes

twin pollen
#

no no I mean

#

since the list_of_tuples is still a list, it can be changed

worn pulsar
#

you want it to be immutable?

twin pollen
#

the list no

#

in the second func

#

I want it to return the result instead of printing it

#

so say for example I use this for another list I want changed but I dont need to print it

worn pulsar
#

you did just that above

#
    list_of_tuples = sorted(list_of_tuples, key=sort_key, reverse=True)
    return list_of_tuples
#

you dont print it, you return it

twin pollen
#

[('milk', '5.5'), ('candy', '2.5'), ('bread', '9.0')]

worn pulsar
#

or you can simplify that to a single line

#
return sorted(list_of_tuples, key=sort_key, reverse=True)
twin pollen
#
def sort_key(key):
    return float(key[1])

def sort_prices(list_of_tuples):
    """The function receives a list of tuples that each have an item and a price.
    :param list_of_tuples: a list of tuples.
    :type list_of_tuples: list
    :return: a list of tuples sorted by the price of the items in them from the largest to the smallest.
    :rtype: list
    """
    list_of_tuples = sorted(list_of_tuples, key=sort_key, reverse=True)
    return list_of_tuples

def main():
    # Call the function sort_prices
    products = [('milk', '5.5'), ('candy', '2.5'), ('bread', '9.0')]
    sort_prices(products)
    print(products)
    
if __name__ == "__main__":
    main()
twin pollen
#

wait

#

I think I get it

worn pulsar
#

yes, you dont make any changes to products and print it at the end of main function

twin pollen
#

I would need to do products = sort...

#

yeah works

#

well thank you both !

worn pulsar
#

no problem!

#

also, if you want to keep the product: price thingy

#

instead of just getting the prices

#

u could use a dictionary for that

twin pollen
#

haha theres so many things I need to learn

#

!d dictionary

echo gustBOT
#

An associative array, where arbitrary keys are mapped to values. The keys can be any object with __hash__() and __eq__() methods. Called a hash in Perl.

red flume
#

and since your data is conveniently formatted, you can just

#

!e

items = [('milk', '5.5'), ('candy', '2.5'), ('bread', '9.0')]
print( dict(items) )
echo gustBOT
#

@red flume :white_check_mark: Your 3.12 eval job has completed with return code 0.

{'milk': '5.5', 'candy': '2.5', 'bread': '9.0'}
worn pulsar
#
products = {
    'milk': 5.5,
    'candy': 2.5,
    'bread': 9.0
}

and to get candy price:

products['candy'] # returns 2.5
#

and, you might remember my example

#

i showed sorted function on a dictionary

twin pollen
#

that would be more useful

#

well im sure wiith time ill simplify everything

worn pulsar
#

!e

products = {
    'milk': 5.5,
    'candy': 2.5,
    'bread': 9.0
}

# sorted() on a dictionary returns a list of keys ['candy', 'milk', 'bread']
# dictionary.get(key) returns a value of a key, so it sorts by the price (value of each key)
sorted_products = sorted(products, key=products.get)

for key in sorted_products:
    print(f'{key = }, {products[key] = }')
echo gustBOT
#

@worn pulsar :white_check_mark: Your 3.12 eval job has completed with return code 0.

001 | key = 'candy', products[key] = 2.5
002 | key = 'milk', products[key] = 5.5
003 | key = 'bread', products[key] = 9.0
twin pollen
#

is it supposed to say products key

worn pulsar
#

!e

import math
print(f'{5 + 5 = }')
print(f'{math.pi = }')
echo gustBOT
#

@worn pulsar :white_check_mark: Your 3.12 eval job has completed with return code 0.

001 | 5 + 5 = 10
002 | math.pi = 3.141592653589793
twin pollen
#

xD

#

I meant the word key

#

like if I wanted to change the result to :

worn pulsar
twin pollen
#
001 | name = 'candy', price = 2.5
002 | name = 'milk', price = 5.5
003 | name = 'bread', price = 9.0
worn pulsar
#

yes

worn pulsar
#

you could do that like so

#

!e

products = {
    'milk': 5.5,
    'candy': 2.5,
    'bread': 9.0
}

# sorted() on a dictionary returns a list of keys ['candy', 'milk', 'bread']
# dictionary.get(key) returns a value of a key, so it sorts by the price (value of each key)
sorted_products = sorted(products, key=products.get)

for key in sorted_products:
    print(f'name = {key}, price = {products[key]}')
echo gustBOT
#

@worn pulsar :white_check_mark: Your 3.12 eval job has completed with return code 0.

001 | name = candy, price = 2.5
002 | name = milk, price = 5.5
003 | name = bread, price = 9.0
twin pollen
#
products = {
    'milk': 5.5,
    'candy': 2.5,
    'bread': 9.0
}

# sorted() on a dictionary returns a list of keys ['candy', 'milk', 'bread']
# dictionary.get(key) returns a value of a key, so it sorts by the price (value of each key)
sorted_products = sorted(products, key=products.get)

for name in sorted_products:
    price = products[name]
    print(f'{name = }, {price = }')
#

yeah

#

I guessed

worn pulsar
#

well u wont be able to do it that way tho

#

everything inside { } is a python expression

#

ah wait

#

didnt notice that you created those variables ๐Ÿ’€

twin pollen
#

xD

#

not the best way

#

but works right ?

worn pulsar
#

!e

products = {
    'milk': 5.5,
    'candy': 2.5,
    'bread': 9.0
}

# sorted() on a dictionary returns a list of keys ['candy', 'milk', 'bread']
# dictionary.get(key) returns a value of a key, so it sorts by the price (value of each key)
sorted_products = sorted(products, key=products.get)

for name in sorted_products:
    price = products[name]
    print(f'{name = }, {price = }')
echo gustBOT
#

@worn pulsar :white_check_mark: Your 3.12 eval job has completed with return code 0.

001 | name = 'candy', price = 2.5
002 | name = 'milk', price = 5.5
003 | name = 'bread', price = 9.0
worn pulsar
#

yep

#

actually a pretty cool way ngl

twin pollen
#

the smartest ideas come from the dumb ones I guess

#

alr see you ! and thx again

#

!close

echo gustBOT
#
Python help channel closed

This help channel has been closed and it's no longer possible to send messages here. If your question wasn't answered, feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.