Re:Lesser known parts of Python standard library – Trickster...
by judicious on Thursday September 05, 2024 @11:04AM
(#41457315)
Dictionary comprehensions can be very elegant. List and dictionary comprehensions are very powerful and expressive abstractions. In fact, while not good practice you can pretty much write all Python code inside comprehensions including stuff regarding mutation.
This is valid(as in it will run, but highly unidiomatic) code:
quicksort = lambda arr: [pivot:=arr[0], left:= [x for x in arr[1:] if x < pivot], right := [x for x in arr[1:] if x >= pivot], quicksort(left) + [pivot] + quicksort(right)][-1] if len(arr) > 1 else arr
print(quicksort([1, 33, -4, -2, 110, 5, 88]))
Re:Lesser known parts of Python standard library – Trickster...
by hansvm on Thursday September 05, 2024 @02:29PM
(#41459237)
Sometimes mutations in comprehensions are very expressive.
def scan(items, f, initial):
x = initial
return (x := f(x, y) for y in items)
There are lots of other short ways to write `scan`, but I don't think any of them map so clearly to a naive definition of what it's supposed to do.
Re:Lesser known parts of Python standard library – Trickster...
by judicious on Thursday September 05, 2024 @03:03PM
(#41459529)
That's incredibly clever, generators are underrated. I once challenged my friend to do leetcode problems with only expressions. Here's levenshtein distance, however it's incredibly clunky.
levenshtein_distance = lambda s1, s2: [matrix := [[0] * (len(s2) + 1) for _ in
range(len(s1) + 1)], [
[
(matrix[i].__setitem__(j, min(matrix[i-1][j] + 1, matrix[i][j-1] +
1, matrix[i-1][j-1] + (0 if s1[i-1] == s2[j-1] else 1))), matrix[i][-1])[1]
for j in range(1, len(s2) + 1)
]
for i in range(1, len(s1) + 1)
], matrix[-1][-1]][-1]
Re:Lesser known parts of Python standard library – Trickster...
by gcr on Thursday September 05, 2024 @11:53AM
(#41457789)
Holy shit that’s really clever. Didn’t know about _make, thank you!
Re:Lesser known parts of Python standard library – Trickster...
by sgarland on Friday September 06, 2024 @07:40AM
(#41465203)
I didn’t either until I read docs tbf. It’s just kind of thrown in as an afterthought for the section, too.
Re:Lesser known parts of Python standard library – Trickster...
by wodenokoto on Thursday September 05, 2024 @12:39PM
(#41458284)
I'm not quite sure how the fetchall() return type looks, but couldn't you just
for name, age, title in cursor.fetchall():
print(name, age, title)
Ofcourse you have to come up with different variable names, but it still seems more elegant to just unpack.
Re:Lesser known parts of Python standard library – Trickster...
by Joker_vD on Thursday September 05, 2024 @01:25PM
(#41458703)
Honestly, the "proper" way should be passing something like this
def namedtuple_factory(cursor, row):
fields = [column[0] for column in cursor.description]
cls = namedtuple("Row", fields)
return cls._make(row)
to the fetchall(), to automatically keep the names in sync with those in the SQL query string.
Re:Lesser known parts of Python standard library – Trickster...
by ttyprintk on Friday September 06, 2024 @07:11AM
(#41465022)
Implemented as conn.row_factory = sqlite3.Row
Re:Lesser known parts of Python standard library – Trickster...
by sgarland on Friday September 06, 2024 @07:44AM
(#41465243)
By default, List[Tuple]]. You could do a list comp over the fetchall(), but at that point there’s already some magic happening, so why not make it explicit?
Re:Lesser known parts of Python standard library – Trickster...
by kstrauser on Thursday September 05, 2024 @02:27PM
(#41459219)
You don't need `_make()` with dataclasses, and you get `asdict()` as a stand-alone function so it doesn't clash with each class's namespace. Here's what your code might look like with them:
import sqlite3
from dataclasses import asdict, dataclass
@dataclass
class EmployeeRecord:
name: str
age: int
title: str
department: str
paygrade: str
conn = sqlite3.connect("/companydata")
cursor = conn.cursor()
cursor.execute("SELECT name, age, title, department, paygrade FROM employees")
for emp in (EmployeeRecord(*row) for row in cursor.fetchall()):
print(emp.name, emp.title)
print(asdict(emp))
[0]: https://docs.python.org/3/library/collections.html#collectio...