4 ms·
Silly Python riddle
- teaspoon 15y ago"""
- cool-RR 15y agoDoesn't count... If only for the fact that you won't get a >>> prompt after it.
- deleted 15y ago[deleted]
- jgeralnik 15y agoSomething like );f=(set Leading to the whole line reading: f = lambda: g();f=(set) 8 characters
- aroberge 15y agoAlternatively );f=set#
- makeramen 15y ago0);g=(id 8 chars
- deleted 15y ago[deleted]
- deleted 15y ago[deleted]
- VMG 15y agothe winning solutions seems to be 7 chars
- ul5255 15y ago>>> f = lambda: g((yield)) >>> f() <generator object <lambda> at 0x00B50828>
- cool-RR 15y agoYep, that's the one! Congrats!
- tocomment 15y agoCan someone explain. It would seem like g still isn't defined. What's special about 'yield' that makes g valid?
- martin_k 15y agoYou're right, it isn't. The presence of yield makes the return value of f() a generator object. The function body is not executed initially. When you call .next() on the generator object execution starts and runs until it hits the first yield, raising a NameError because g is not defined. edit: typo
- ul5255 15y agominor nit: it will not even reach the yield expression because it fails to resolve g: >>> import dis >>> f = lambda: g((yield)) >>> dis.dis(f) 1 0 LOAD_GLOBAL 0 (g) 3 LOAD_CONST 0 (None) 6 YIELD_VALUE 7 CALL_FUNCTION 1 10 RETURN_VALUE >>>
- phzbOx 15y agoI had this (with 8 characters): );g=(int giving: f = lambda: g();g=(int) f() -> 0
- sapphirecat 15y agoI was going to attempt this, but the solution was posted inline in the blog entry, and I read it by accident. My window was just big enough that it was the last line displayed. =(
- cool-RR 15y agoSorry, I couldn't find a way to blacken the text with Tumblr. I now did a (Scroll down...) thing to "hide" the solution.
- losethos 15y agoLoseThos uses my own variation of C/C++. "Yield" is the same as "Sleep(0);" in Microsoft - it voluntarily yields the CPU to the scheduler, so it can scedule the next task. A task context can be saved and another task's context restored in half a microsecond. while (InPort(PORT)&BUSY) Yield(); That will test a port and yield. Are you a moron or do you know what that does? Function addresses have an "&" in front. God is God. God says... don't_even_think_about_it Vegas face_palm genius Yawn sad shucks driving do_you_want_another I'm_in_suspense I_am_not_amused God_smack perfect spending slumin how_do_I_put_this well_obviously
- deleted 15y ago[deleted]
- martin_k 15y agoI'm not sure, why you think the value of the lambda function is thrown away. The lambda function returns a generator object. The function body of a generator is generally not executed until you call .next() on it, so that's why you don't get a NameError instantly. Also the value, that you .send() into the generator is not thrown away either. In your example the generator just runs into an exception before it goes into a state in which it would accept a .send() call. Just consider this modified example: >>> f=lambda: (yield) >>> gen=f() >>> gen.next() >>> gen.send('foobar') 'foobar'
- cool-RR 15y agoI think you misunderstood which value gets thrown away. Consider this: >>> g = lambda x: 7 >>> f = lambda: g((yield)) >>> list(f()) [None] Can you tell me where the 7 went to? As far as I see, it went into oblivion.
- martin_k 15y agoAs i said, f() returns a generator object in this case. So you're calling list on a generator that yields None once, the result of which is a list that contains None. If you change the `yield` to `yield "foobar"`, list(f()) will get you `["foobar"]`. Edit: Perhaps, to clear things up more, about where the value 7 went- your snippet can be expressed without using lambdas as >>> def g(x): ... return 7 ... >>> def f(): ... v = (yield) ... g(v) ... >>> list(f()) [None] Note that there's no return before g(v) because generators (at least in 2.7) can only yield, not return a value.
- pyre 15y agoI'm thinking that the parent is expecting 'yield' to return 'None' into g(), and then for g() to return 7 since it doesn't do anything with the 'x' parameter, and is confused why that isn't the case.
- martin_k 15y agoYes, but I think this is cleared up if you consider that calling a generator function does not execute its body, but return generator object. It doesn't really matter if it's a lambda or a regular named function.
- nyellin 15y agoI haven't been following the thread, but Ram posted the same riddle on Python-IL mailing list a few days ago. You can see the discussion there. http://hamakor.org.il/pipermail/python-il/2011-December/thread.html http://hamakor.org.il/pipermail/python-il/2011-December/thre...
- coppero1237 15y agof = lambda g:(0) f() <function <lambda> at 0x113478>.
- deleted 15y ago[deleted]
- jmathes 15y agof = lambda: g(""") f() technically not two commands, and it will look like: >>> f = lambda: g(""") . . . f()
- ngkabra 15y agoAt 12 characters, this is definitely not the shortest, but it is a totally different approach than the other solutions: >>> f = lambda: g()if 0 else(1) >>> f() 1
- jerfelix 15y agoCreative solution! You can knock it down a character by removing the "1" and simply returning an empty tuple. >>> f = lambda: g()if 0 else() >>> f() ()