2013-11-15 9 views
15

Ich versuche, auseinander zu nehmen und de-verschleiern diese mandlebrot erzeugenden Python-Code:Was bedeutet "für x in y oder z:" in Python?

_          = (
             255, 
             lambda 
           V  ,B,c 
          :c and Y(V*V+B,B, c 
           -1)if(abs(V)<6)else 
       (    2+c-4*abs(V)**-0.4)/i 
       ) ;v,  x=1500,1000;C=range(v*x 
       );import struct;P=struct.pack;M,\ 
      j ='<QIIHHHH',open('M.bmp','wb').write 
for X in j('BM'+P(M,v*x*3+26,26,12,v,x,1,24))or C: 
      i ,Y=_;j(P('BBB',*(lambda T:(T*80+T**9 
        *i-950*T **99,T*70-880*T**18+701* 
       T **9  ,T*i**(1-T**45*2)))(sum(
       [    Y(0,(A%3/3.+X%v+(X/v+ 
           A/3/3.-x/2)/1j)*2.5 
          /x -2.7,i)**2 for \ 
           A  in C 
             [:9]]) 
             /9) 
             ) ) 

Quelle: http://preshing.com/20110926/high-resolution-mandelbrot-in-obfuscated-python/
ich mit einem interessanten Twist for-Schleife gefunden, und ich bin nicht sicher, ob es nur ein Teil der Verschleierung, oder wenn es tatsächlich eine Funktion hat. Die mittlere Zeile:
for X in j('BM'+P(M,v*x*3+26,26,12,v,x,1,24))or C:
Was macht das oder am Ende?

ich wieder schrieb den Code als für Klarheit folgt:

import struct 

image_name = "M.bmp" 
mandlebrot = lambda V,B,c :c and Y(V*V+B,B,c-1) if(abs(V)<6) else (2+c-4*abs(V)**-0.4)/i 
y,x = 600,800 
pixelrange = range(y*x) 
package = struct.pack 

image = open(image_name,'wb').write 

for X in image('BM'+package('<QIIHHHH',y*x*3+26,26,12,y,x,1,24)) or pixelrange: 
    i = 255 
    Y = mandlebrot 
    image(package('BBB',*(lambda T:(T*80+T**9*i-950*T**99,T*70-880*T**18+701*T**9,T*i**(1-T**45*2)))(sum([Y(0,(A%3/3.+X%y+(X/y+A/3/3.-x/2)/1j)*2.5/x-2.7,i)**2 for A in pixelrange [:9]])/9))) 
+2

Die ganze Geschichte davon, wie Sie dieses interessante 'für x in y oder z 'fanden, ist für die Frage nicht notwendig, aber ich bin froh, dass Sie es eingeschlossen haben. Es ist ziemlich cool. – SethMMorton

+0

Ich habe erwartet, dass die Antwort viel komplexer sein wird, weil ich nicht wusste "für x in y oder z" ist eigentlich eine ordnungsgemäße/gültige Verwendung einer for-Schleife. Wie immer überraschte Python mich mit seiner Einfachheit. –

Antwort

16

tun:

for x in y or z: 

ist die gleiche wie:

for x in (y or z): 

Wenn y-True auswertet, Die For-Schleife wird durchlaufen. Sonst wird es durch z iterieren.

Unten finden Sie eine Demonstration:

>>> y = [1, 2, 3] 
>>> z = [4, 5, 6] 
>>> for x in y or z: 
...  print x 
... 
1 
2 
3 
>>> y = [] # Empty lists evaluate to False in Python 
>>> for x in y or z: 
...  print x 
... 
4 
5 
6 
>>> 
+0

Es ist erstaunlich, wie mächtig ein schneller Test im CLI sein kann. – Matt

3

or den ersten Operanden zurückgibt, wenn es boolean true ist, ansonsten wird die zweite. Boolean false bedeutet grundsätzlich 0, False, None oder ein "leeres Objekt" (leere Zeichenfolge, Liste usw.); Wahrheit ist alles andere. So j('BM'+P(M,v*x*3+26,26,12,v,x,1,24)) or C wertet das Ergebnis des j(...) Aufrufs aus, wenn das Ergebnis nicht leer ist, andernfalls C. Es wird also über das Ergebnis von j(...) iterieren, wenn dieses Ergebnis nicht leer ist, andernfalls wird es über C iterieren.