2014-11-15 6 views
1

Учимся быть pythonic в 2.7. Есть ли способ избежать явного цикла? answer = [5, 4, 4, 3, 3, 2]Есть ли более питонический способ написать

import numpy as np 
import scipy.special as spe 

nmax = 5  # n = 0, 1 ...5 
mmax = 7  # m = 1, 2 ...7 
big = 15. 
z = np.zeros((nmax+1, mmax)) 
for i in range(nmax+1): 
    z[i] = spe.jn_zeros(i, mmax) 
answer = [np.max(np.where(z[i]<big))+1 for i in range(nmax+1)] 
print answer # list of the largest m for each n where the mth zero of Jn < big 
+0

@twasbrillig поймал ошибку, включило исправление nmax -> nmax + 1, затем удалил +1 из mmax, где он был неправильно применен. – uhoh

+0

... и я добавил разъяснения. n = 0 относится к J0 и т. д., и помните, что первый нуль не тот, который находится в начале координат (при n> 0). – uhoh

ответ

5

Что здесь значит «больше Pythonic». Один из основных принципов Python - читаемость, поэтому, если нет реальной причины для избавления от циклов, просто сохраните их.

Если вы действительно хотите, чтобы увидеть некоторые другие способы сделать то же самое, то:

z = np.zeros((nmax+1, mmax)) 
for i in range(nmax+1): 
    z[i] = spe.jn_zeros(i, mmax) 

может быть заменен:

func = lambda i:spe.jn_zeros(i,mmax) 
np.vstack(np.vectorize(func, otypes=[np.ndarray])(np.arange(nmax+1))) 

, который немного быстрее (1,35 мс против 1,77 мс), но, вероятно, менее питоновских и

[np.max(np.where(z[i]<big))+1 for i in range(nmax+1)] 

может быть заменен

np.cumsum(z < big,axis=1)[:,-1] 

, о котором я бы сказал, более Pythonic (или numpythonic) и намного быстрее (20 us против 212 us).

+1

Спасибо за ваш ответ @ebarr. Переход от float к bool до целого в десятки символов довольно круто! (напоминание о себе: это использует монотонность jn_zeros) – uhoh

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