2009-08-22 26 views
6

पर पुनरावृत्त करने का पाइथोनिक तरीका मेरे पास पाइथन में एक 3 डी सरणी है और मुझे सरणी में सभी क्यूब्स पर फिर से चलने की आवश्यकता है। ,3 डी सरणी

array[(x + 0, y + 0, z + 0)] 
array[(x + 1, y + 0, z + 0)] 
array[(x + 0, y + 1, z + 0)] 
array[(x + 1, y + 1, z + 0)] 
array[(x + 0, y + 0, z + 1)] 
array[(x + 1, y + 0, z + 1)] 
array[(x + 0, y + 1, z + 1)] 
array[(x + 1, y + 1, z + 1)] 

सरणी एक Numpy सरणी है कि हालांकि वास्तव में आवश्यक नहीं है: यह, के लिए सरणी के आयाम में सभी (x,y,z) मैं घन का उपयोग करने की जरूरत है। मुझे numpy.fromfile() का उपयोग करके एक-लाइनर के साथ डेटा को पढ़ने में बहुत आसान लगा।

क्या इनमें से अधिक से अधिक पुन: प्रयास करने के लिए कोई और पाइथोनिक तरीका है? यह बस पाइथन वाक्यविन्यास का उपयोग कर सी की तरह दिखता है।

for x in range(x_dimension): 
    for y in range(y_dimension): 
     for z in range(z_dimension): 
      work_with_cube(array[(x + 0, y + 0, z + 0)], 
          array[(x + 1, y + 0, z + 0)], 
          array[(x + 0, y + 1, z + 0)], 
          array[(x + 1, y + 1, z + 0)], 
          array[(x + 0, y + 0, z + 1)], 
          array[(x + 1, y + 0, z + 1)], 
          array[(x + 0, y + 1, z + 1)], 
          array[(x + 1, y + 1, z + 1)]) 
+0

इस http द्वारा उत्तर दिया जाएगा map(xrange, ...) पास करना : //stackoverflow.com/questions/1280667/in-python-is-there-an-easier-way-to-write-6-nested-for-loops? – tom10

+0

यह सीमा होगी (...- 1), यहां ... – EOL

+0

असल में, हाँ @ tom10, यह –

उत्तर

14

, विशेष रूप से itertools.productitertools पर एक नज़र डालें। आप

import itertools 

for x, y, z in itertools.product(*map(xrange, (x_dim, y_dim, z_dim)): 
    ... 

साथ एक में तीन छोरों सेक कर सकते हैं तुम भी घन इस तरह से बना सकते हैं:

cube = numpy.array(list(itertools.product((0,1), (0,1), (0,1)))) 
print cube 
array([[0, 0, 0], 
     [0, 0, 1], 
     [0, 1, 0], 
     [0, 1, 1], 
     [1, 0, 0], 
     [1, 0, 1], 
     [1, 1, 0], 
     [1, 1, 1]]) 

और एक सरल इसके अलावा द्वारा ऑफसेट जोड़ने

print cube + (10,100,1000) 
array([[ 10, 100, 1000], 
     [ 10, 100, 1001], 
     [ 10, 101, 1000], 
     [ 10, 101, 1001], 
     [ 11, 100, 1000], 
     [ 11, 100, 1001], 
     [ 11, 101, 1000], 
     [ 11, 101, 1001]]) 

जो करने के लिए होगा अपने मामले में cube + (x,y,z) पर अनुवाद करें। अपने कोड के बहुत कॉम्पैक्ट संस्करण होगा

import itertools, numpy 

cube = numpy.array(list(itertools.product((0,1), (0,1), (0,1)))) 

x_dim = y_dim = z_dim = 10 

for offset in itertools.product(*map(xrange, (x_dim, y_dim, z_dim))): 
    work_with_cube(cube+offset) 

संपादित: itertools.product, अलग तर्क से अधिक उत्पाद बनाता है यानी itertools.product(a,b,c), तो मैं साथ *map(...) रूप

+0

प्रश्न का उत्तर देता है, यह त्रुटि में परिणाम: ValueError: आकार मेल नहीं: ऑब्जेक्ट को एक आकार में प्रसारित नहीं किया जा सकता –

+0

... हालांकि, आपके उदाहरण में 'ऑफ़सेट' के बजाय '(x, y, z) 'का उपयोग करके –

+0

\ * sigh * हमेशा इसे अपने कोड का परीक्षण करने से पहले –

8
import itertools 
for x, y, z in itertools.product(xrange(x_size), 
           xrange(y_size), 
           xrange(z_size)): 
    work_with_cube(array[x, y, z])