2013-04-08 4 views
3

Я хотел бы знать, есть ли какие-либо другие способы циклирования и управления данными, расположенными в отдельных массивах.Есть ли более чистый способ, чем использование для циклов

import numpy as np 

a = np.arange(2) 
b = np.arange(5) 
c = np.arange(5) 

l1 = [] 
for x in a: 
    l2 = [] 
    for y in b: 
     l3 = [] 
     y = x + 1 
     for z in c: 
      z = x + y 
      t = (x,y,z) 
      l3.append(t) 
     l2.append(l3) 
    l1.append(l2) 
print l1 
+6

Что именно является код пытается сделать? – NPE

+1

Пожалуйста, будьте конкретнее, что вы хотите сделать? – vivek

+0

Im строит данные на основе разных параметров, а затем строит их. Эти параметры являются массивами. – Wallace

ответ

7

Этот код делает именно то, что вы делаете.

def method(lst, range1, range2): 
    for i in lst: 
     yield [[(i, i+1, 1+(i*2))]*range2]*range1 

Может даже быть превращен в выражение генератора:

def gen_method(lst, r1, r2): 
    return ([[(i, i+1, 1+(i*2))]*r2]*r1 for i in lst) 

проверить это самостоятельно, если вы хотите.


Мои тесты:

a = range(2) 
b = range(5) 
c = range(5) 

def your_method(a, b, c): 
    l1 = [] 
    for x in a: 
     l2 = [] 
     for y in b: 
      l3 = [] 
      y = x + 1 
      for z in c: 
       z = x + y 
       t = (x,y,z) 
       l3.append(t) 
      l2.append(l3) 
     l1.append(l2) 
    return l1 

def my_method(lst, range1, range2): 
    for i in lst: 
     yield [[(i, i+1, 1+(i*2))]*range2]*range1 

yours = your_method(a, b, c) 
mine = list(my_method(a, len(b), len(c))) 

print yours 
print '===' 
print mine 
print '===' 
print yours == mine 

>>> 
[[[(0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1)], [(0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1)], [(0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1)], [(0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1)], [(0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1)]], [[(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)], [(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)], [(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)], [(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)], [(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)]]] 
=== 
[[[(0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1)], [(0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1)], [(0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1)], [(0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1)], [(0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1)]], [[(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)], [(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)], [(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)], [(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)], [(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)]]] 
=== 
True 
1

Ну, вы можете сжимать код, используя списковых:

[[[(x,x+1,x*2 +1)]*len(c)]*len(b) for x in a] 

Что это делает петля для всех х а и создать список элементов, где каждый элемент является списком, сгенерированным для всех y в b, где каждый элемент содержит список: (x,x+1,2*x+1) для всех z в c.

+0

Это займет намного больше времени, чем мой пример, зацикливание элементов в 'c' и' b' - пустая трата времени, вам нужно только их длина. Вы можете проверить с помощью модуля timeit. –

+0

@InbarRose: Как насчет сейчас? – Manishearth

+0

Да, и теперь он почти как мой, но поскольку он не является выражением генератора, он будет иметь более тяжелые потери в памяти. Все зависит от предпочтений, я предпочитаю генераторы, некоторые предпочитают простые списки. Кроме того, вы делаете 'x + x + 1' и я делаю' 1+ (x * 2) ', что быстрее. –

0

Альтернативный подход заключается в использовании itertools, конвертировать полученный список numpy array и изменить его

import numpy as np 
import itertools as it 

a = np.arange(2) 
b = np.arange(5) 
c = np.arange(5) 

l1 = np.array([(i, i+1, i*2+1) for i, rb, rb in it.product(a, b, c)]) 
l1 = l1.reshape(len(a), len(b), len(c), len(d[0])) 

Это может быть, что это получает больше памяти, потребляющего, чем все другие подходы, по мере увеличения размера, но только две строки и создают уникальные элементы для каждого триплекса, а не просто создают несколько указателей на один и тот же объект.

Редактировать

Другим способом, что также позволяет сохранить триплет (я, я + 1, я * 1 + 1) в виде списка:

l1 = np.empty([len(a), len(b), len(c)], dtype=object) 
for i, rb, rb in it.product(a, b, c): 
    l1[i,ra, rb] = (i, i+1, i*2+1) 
+0

«только два строки "длина кода не имеет ничего общего с эффективностью, на самом деле, python - это все о удобочитаемости, в любом случае один из моих ответов - это * также * 1 лайнер (внутри вызова функции - так что это также две строки) .... Это не быстрее и не читается. –

+0

ты меня запустил только потому, что «только две линии»? Я знаю, что короткий не означает более эффективного, и я не пытался играть, делая это короче. Я просто хотел написать короткое решение, без проблемы, которая (я думаю) влияет на два других ответа. –

Смежные вопросы