Re:Python: Uncovering the Overlooked Core Functionalities
by noitpmeder on Monday July 24, 2023 @09:59PM
(#36856931)
Anyone have good examples of how/when to actually use this? I've personally never interacted with or written a generator that expects to receive values.
Re:Python: Uncovering the Overlooked Core Functionalities
by pizza on Monday July 24, 2023 @10:36PM
(#36857174)
Anything with feedback control. Updating a priority queue's weights, adaptive caching, adaptive request limiting, etc. Ironically it looks like HN itself rate limited me the first time I tried to reply lol
Re:Python: Uncovering the Overlooked Core Functionalities
by luckycharms810 on Monday July 24, 2023 @11:48PM
(#36857633)
This is the basis of most older async frameworks (see: Tornado, Twisted). A while ago I put together a short talk on how to go from this feature -> a very basic version of Twisted's @inline_callback decorator.
Re:Python: Uncovering the Overlooked Core Functionalities
by strunz on Tuesday July 25, 2023 @12:43AM
(#36857984)
I actually had a great use case for this last week. Needed to flatten a list of nested dicts, e.g.:
[
{"name": "/dev/loop0"},
{"name": "/dev/loop1"},
{"name": "/dev/loop2"},
{
"name": "/dev/sda",
"children":
[
{
"name": "/dev/sda1",
"children":
[{"name": "/dev/mapper/lubuntu--vg-root"}, {"name": "/dev/mapper/lubuntu--vg-swap_1"}],
},
],
},
{"name": "/dev/sdb", "children": [{"name": "/dev/sdb1"}, {"name": "/dev/sdb2"}]},
{"name": "/dev/sdc", "children": [{"name": "/dev/sdc1"}, {"name": "/dev/sdc9"}]},
]
Wound up writing a recursive generator (with some help from #python on IRC): def flatten(items):
for item in items:
yield {k:v for k,v in item.items() if k != 'children'}
if 'children' in item:
yield from flatten(item['children'])
which results in: [{'name': '/dev/loop0'},
{'name': '/dev/loop1'},
{'name': '/dev/loop2'},
{'name': '/dev/sda'},
{'name': '/dev/sda1'},
{'name': '/dev/mapper/lubuntu--vg-root'},
{'name': '/dev/mapper/lubuntu--vg-swap_1'},
{'name': '/dev/sdb'},
{'name': '/dev/sdb1'},
{'name': '/dev/sdb2'},
{'name': '/dev/sdc'},
{'name': '/dev/sdc1'},
{'name': '/dev/sdc9'}]
Re:Python: Uncovering the Overlooked Core Functionalities
by TrianguloY on Tuesday July 25, 2023 @02:51AM
(#36858847)
I see your function and "yield" (pun definitely intended) the following:
def flatten(children=[], **other):
if other: yield other
for child in children: yield from flatten(**child)
Re:Python: Uncovering the Overlooked Core Functionalities
by strunz on Tuesday July 25, 2023 @11:16AM
(#36863557)
That's pretty brilliant to use `children` as the keyword name, thanks!
Re:Python: Uncovering the Overlooked Core Functionalities
by noitpmeder on Friday July 28, 2023 @03:26AM
(#36903946)
Thanks for the example, but I was more looking for something that uses "generator.send(...)". I definitely agree that yielding items out of generators is extremely useful, but not so sure on examples of generators that are sent values.
Re:Python: Uncovering the Overlooked Core Functionalities
by noman-land on Tuesday July 25, 2023 @12:53AM
(#36858045)
I am a python noob and this is going to take me some time to process.
Re:Python: Uncovering the Overlooked Core Functionalities
by contravariant on Tuesday July 25, 2023 @05:35AM
(#36859971)
Best way to think about it is that a generator can throw some questions back to the caller. It always looks a bit messy though.
question_bank={'1+1' : '2', '2+3' : '5'}
def Quiz():
for question, correct_answer in question_bank.items():
answer = yield question
if answer == correct_answer:
print('Correct!')
else:
print('Wrong.')
yield 'Finished!'
question = Quiz()
q = next(question)
while q != 'Finished!':
q = question.send(input(q))
https://stackoverflow.com/questions/20579756/passing-value-t...
And don't forget "yield from" (same as yielding all values in a list, but keeps the original generator! You can send data back to the list if it is itself another generator!)