Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a Python equivalent of the Haskell 'let'

Is there a Python equivalent of the Haskell 'let' expression that would allow me to write something like:

list2 = [let (name,size)=lookup(productId) in (barcode(productId),metric(size))              for productId in list] 

If not, what would be the most readable alternative?

Added for clarification of the let syntax:

x = let (name,size)=lookup(productId) in (barcode(productId),metric(size)) 

is equivalent to

(name,size) = lookup(productId) x = (barcode(productId),metric(size)) 

The second version doesn't work that well with list comprehensions, though.

like image 762
Perseids Avatar asked Aug 31 '12 16:08

Perseids


People also ask

Does Python have let?

This ability doesn't exist in Python, because of the thought that when people write something like: if row = db.


2 Answers

You could use a temporary list comprehension

[(barcode(productId), metric(size)) for name, size in [lookup(productId)]][0] 

or, equivalently, a generator expression

next((barcode(productId), metric(size)) for name, size in [lookup(productId)]) 

but both of those are pretty horrible.

Another (horrible) method is via a temporary lambda, which you call immediately

(lambda (name, size): (barcode(productId), metric(size)))(lookup(productId)) 

I think the recommended "Pythonic" way would just be to define a function, like

def barcode_metric(productId):    name, size = lookup(productId)    return barcode(productId), metric(size) list2 = [barcode_metric(productId) for productId in list] 
like image 173
huon Avatar answered Sep 23 '22 12:09

huon


Recent python versions allows multiple for clauses in a generator expression, so you can now do something like:

list2 = [ barcode(productID), metric(size)           for productID in list           for (name,size) in (lookup(productID),) ] 

which is similar to what Haskell provides too:

list2 = [ (barcode productID, metric size)         | productID <- list         , let (name,size) = lookup productID ] 

and denotationally equivalent to

list2 = [ (barcode productID, metric size)          | productID <- list         , (name,size) <- [lookup productID] ] 
like image 40
b0fh Avatar answered Sep 25 '22 12:09

b0fh