2013-11-15 36 views
15

Staram się rozbierać i de-zaciemniać ten mandlebrot generowania kodu Pythona:Co robi "dla x w y lub z:" w Pythonie?

_          = (
             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) 
             ) ) 

źródło: http://preshing.com/20110926/high-resolution-mandelbrot-in-obfuscated-python/
znalazłem dla pętli z ciekawym akcentem, a nie jestem pewien, czy to tylko część obfuskacji lub jeśli faktycznie ma jakąś funkcję. Środkowa linia:
for X in j('BM'+P(M,v*x*3+26,26,12,v,x,1,24))or C:
Co robi lub robi na końcu?

I ponownie napisał kod w następujący sposób dla jasności:

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

Cała historia tego, jak znalazłeś to interesujące 'na x in y lub z' nie jest konieczna do pytania, ale cieszę się, że go włączyłeś. To całkiem fajne. – SethMMorton

+0

Spodziewałem się, że odpowiedź będzie o wiele bardziej złożona, ponieważ nie wiedziałem, że "dla x w y lub z" jest właściwie właściwym/prawidłowym użyciem pętli for. Jak zwykle, Python zaskoczył mnie swoją prostotą. –

Odpowiedz

16

robi:

for x in y or z: 

jest taka sama, jak:

for x in (y or z): 

Jeśli y ocenia się True, pętla for przerwie ją. W przeciwnym razie będzie iterować przez z.

Poniżej jest wykazanie:

>>> 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

To niesamowite, jak potężny może być szybki test w cli. – Matt

3

or zwraca pierwszy argument, jeśli jest logiczna prawda, inaczej sekund. Wartość logiczna fałszu logicznego oznacza w zasadzie 0, fałsz, brak lub "pusty obiekt" (pusty ciąg, lista itp.); boolean true to wszystko inne. Tak więc j('BM'+P(M,v*x*3+26,26,12,v,x,1,24)) or C oceni wynik połączenia j(...), jeśli ten wynik nie jest pusty, w przeciwnym razie do C. Tak będzie iterować wynik j(...), jeśli ten wynik nie jest pusty, w przeciwnym razie będzie iterować nad C.