10 ms·
Nastiest Python list comprehension ever
- agentultra 16y agoDoes that even run? :) Nested comprehensions are one of the things I hate about Python actually. The functions in itertools are so much clearer. I can't really think of a good reason to use nested comprehensions... they become unreadable really fast!
- cool-RR 16y agoThe nesting of list comprehension is just an aperitif in this function.
- deleted 16y ago[deleted]
- StavrosK 16y ago> Does anyone have a suggestion on how to do it? Yes, provide more details so I don't have to spend twenty minutes figuring out what it does. (Going by my three-second-look gut feeling: It's the Sieve of Eratosthenes)
- sibsibsib 16y agoit generates a list of prime numbers up to 'n', including some false positives. The author wasn't kidding about it being nasty to read...
- StavrosK 16y agoLooking at it a bit more, it's sort-of-obvious that that's what it is, if you've seen the Sieve before. However: > i for a[::i] in <whatever> Mind blown. How does assigning to an array even work? I'm guessing this is way-undefined-speak for setting elements, and I am simultaneously dazzled by its brilliance and horrified by its stupidity.
- cool-RR 16y agoYes, that was the desired effect :)
- zem 16y agoyeah, i figured out what it did by playing in the repl, but i still can't find it documented anywhere.
- StavrosK 16y agoI tried a bit in the REPL and couldn't replicate it completely, but I didn't try hard. It seems to only work because of the CPython internals, so it seems to be implementation-specific and undocumented.
- cool-RR 16y agoNot true, it's part of Python's syntax. Here it is in Pypy: Python 2.5.2 (79560, Nov 26 2010, 14:57:55) [PyPy 1.4.0] on win32 >>> a = [1, 2 ,3] >>> for a[:] in [[6, 7, 8]]: ... pass >>> print(a) [6, 7, 8]
- StavrosK 16y agoSo what does it do? Run the expression first and assign to whatever's there? It seems that it would only work to assign to a slice, as anything else would be overwritten, but why?
- srean 16y agoYes, but I could not understand why one needs list(range(n)) as opposed to range(n) and why the double indexing of a in i in a[:][2:] if a[i] == i]. Am I missing something ? I think it would work without those. Edit: Yo La Tengo. Deviousness aside the code is quite nice. It would be fun to optimize it but without breaking its spirit.
- cookiecaper 16y agoThis is probably a Python 3 program. The list() wrapped around range() makes a list out of an iterator -- range() now returns an iterator in Py 3. See http://diveintopython3.org/porting-code-to-python-3-with-2to3.html#xrange http://diveintopython3.org/porting-code-to-python-3-with-2to...
- cool-RR 16y agoThe `list(range(n))` is for Python 3 compatibility :) The [:] you mentioned is indeed redundant, I removed it. Thanks.
- sophacles 16y agolist(range(n)) -- I sometimes do this because I never can remember if they have finally gotten around to making range a generator yet, and better safe than sorry. a[:][2:] -- maybe the author doesn't know that any slice returns a new list? Maybe he just wants to be even more mysterious?
- StavrosK 16y agolist(range(n)) is probably because the author was using Python 3, in which range() returns an iterator (think xrange in 2.x). The double indexing is probably because a[:] returns a copy of a and the author doesn't want to iterate over the modified array, since he modifies it down the line (although the [2:] would copy it too, so no idea). An alternative to a[:][2:] would just be range(2, n), but the author clearly doesn't want it to be readable.
- kingkilr 16y ago(Going by my three-second-look gut feeling: It's the Sieve of Eratosthenes) A broken one, this seems like advertising that you hole in one'd a sand trap.
- acangiano 16y ago>>> def mystery(n): It's a buggy implementation of primes_below(n) through a sieve. "There should be one - and preferably only one - obvious way to do it." And this ain't it.
- ffffruit 16y agoCan somebody from the Perl community please but this guy in the right place by supplying a one-liner Perl golf quadruple map call?
- khafra 16y agoGood point. "Least readable Python code" is a distinction similar to "smallest market cap on the Fortune 50" or "fattest Olympic decathlete."
- btilly 16y agoI disbelieve. Which would you prefer to read to get the output of a system call? `your system call and args` subprocess.Popen(['your', 'system', 'call', 'and', 'args'], stdout=subprocess.PIPE).communicate()[0] The former is the traditional syntax supported in various shells, Perl, and Ruby. The latter is what you need if you want your code to run in Python 2.6. And this is before we get into the fact that the minutia of syntax and layout is only a minor factor in the maintainability of large projects.
- ominous_prime 16y agoPython still has (even in 3.2) os.system, which is the equivalent of the backticks from perl/shell. The subprocess module is preferred because you have more control and options than simply deferring to the C library's system() call.
- btilly 16y agoPython still has (even in 3.2) os.system, which is the equivalent of the backticks from perl/shell. Sorry, but you're wrong. The os.system call is the equivalent of Perl's system call. It runs an external command and gives you a return code, but does not give you the text generated by said system call. The officially recommended (as of Python 2.6) way to get said text is what I wrote. The deprecated but possibly still working solution is to use os.popen. That is cleaner for this common use case, but I chose to stick to the the officially recommended solution instead. Eventually the Python folks realized that the blessed One True Way to do it was actually pretty horrible, and so they added subprocess.check_output in 2.7.
- francoisdevlin 16y agoThis is why moving away from higher order functions and towards list comprehensions is a mistake. Bad BDFL, bad!
- RiderOfGiraffes 16y agoWhat, you mean because HOFs can't be tortured into unreadability? Readability requires that the programmer conspires with both the language and the reader. Unreadable code can be written in any style, any paradigm and any language. Sometimes it doesn't even take effort, talent or skill.
- stcredzero 16y agoIsn't the point of a list comprehension - comprehension? (It's a paraphrase of something Feynman once said to Murray Gell-Mann.)
- jakozaur 16y agoCorrected version: def mystery(n): a = list(range(n)) return [[i for a[::i] in [([0]*n)[::i]]][0] for i in a[2:] if a[i]]
- shangaslammi 16y agoWow. I hadn't realized that syntax like "for a[::i] in" is valid Python. Attribute assignment (for x.foo in) seem to work too. I'm not sure if there will ever be any reason to use those in real code, but it's nice trivia to know for Python golfing.
- lmkg 16y agoI think it's a testimony to the readability of Python that I've never even programed in the language, nor am I familiar with the finer points of the list syntax (a[::2]?!), and yet this mucked up piece of shit nonetheless gave me the first impression of a prime number sieve. I actually still don't understand how the sieve works, but it somehow just looks like one. Or is it just the case that assuming every obfuscated loop is a prime number sieve is disproportionately likely to be true?
- saurik 16y agoMy favorite to date is: bps = [map(int, bps.split('/')) if isinstance(bps, str) else bps for bps in bps if bps] The clause "else bps for bps in bps if bps" made me incredibly incredibly happy.