2016-03-19 13 views
6

Ben sadece işlevinde t değişken için for döngü kullanmak istiyorum: Ben t değeri 1'den 99'a gidin ve tüm değerin bir listesini yazdırmak istediğinizİki değişkene bağlı bir işlevde yalnızca bir değişken için 'for' döngüsünü nasıl kullanabilirim?

l = [] 

def func(s): 
    for i in range(1, 100): 
     t = i 
     p = t * 2 + s * 2 
    return p 

l.append(func(10)) 

print l 

, ama her zaman ben l = [218] elde et.

+2

@AlbertoBonsanto: girintiyi sabitlemeyle ilgili sorun şimdi açık olmalıdır. Bu '' '' '' '' '' '' '' '' 'fonksiyonunun gerçekten bir parçası mıydı? Ve neden işlev gövdesini girmedin? –

+0

@MartijnPieters Üzgünüm, tam olarak düzenleme yapıyordum! Seninkini yazmış gibi yapmadım! –

+0

Bunu düşünün mü? func = lambda s: [(t * 2) + s * 2 t in menzili için (1, 100)] – Signal

cevap

41

NumPy yüklendiğinizi varsayalım (en azından sizin orijinal sorunuzu sormalısınız), böylece nasıl bir yol göstereceğim (herhangi bir listeye-comprehensions ve açık tekrarlamalar olmadan) çok verimli bir şekilde numpy-arrays kullanarak sonuç almak:

> import numpy as np 
> s = 10 
> l = np.arange(1, 100) * 2 + s * 2 # Arrange produces an array. Syntax is like "range". 
> print(l) 

array([ 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 
     48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 
     74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 
     100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 
     126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 
     152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 
     178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 
     204, 206, 208, 210, 212, 214, 216, 218]) 

Ben NumPy diziler üzerinde matematiksel işlemler tüm unsurları etkilediği gerçeğini kullandı. Bu nedenle operasyon yazmak çok kolaydır: o 2 ve numpy.arange her eleman çarpar çünkü arasındaki tüm sayıları içeren bir dizi oluşturmak için bir olasılık, np.arange(1, 100) * 2 bir ile start ve stop verilen isteğe bağlı bir step (sadece python range gibi).

NumPy ile append tek değerleri için iyi bir seçim olmaz (çünkü bu tüm diziyi yeniden oluşturur ve değerleri eklemez). Çoğu durumda, son boyut ve şekle sahip bir dizi oluşturmak ve doğrudan üzerinde çalışmak en iyisidir. Tabii ki concatenate veya append farklı NumPy dizileri yapabilirsiniz, ancak belirtildiği gibi her zaman tamamen yeni bir dizi oluşturur ve bu nedenle çok verimli değildir (düzenli olarak kullanılıyorsa). işe yaramadı neden ilk denemede


Yani şimdi birkaç gözlemleri ve: İşleviniz sayıların sürü oluşturdu, ancak bu her döngüde bunları geçersiz kılar ve sadece sonuncusu verir:

def func(s): 
    for i in range(1, 100): 
     t = i 
     p = t * 2 + s * 2 
     # Next iteration of the loop just overwrites p 
    # Returns only the last p 
    return p 

Sen (yerine return ait yield ile) bu bir jeneratör yapabilir, ama bu overkill burada muhtemelen, orada ar beri

l = [] 
def func(s): 
    for i in range(1, 100): 
     p = i * 2 + s * 2 
     yield p 

l.append(list(func(10))) # Need to convert the generator to a list here. 
# In this case a simple "l = list(func(10))" would be easier if you don't need to append. 
+0

jeneratörü 'verim' kullanırken, sonuçlar bir listede 1 eleman olarak ortaya çıkıyor. 'def func (s)' ı nasıl yazdırabilirim böylece başka bir listeye göre çizim yapabilirim –

+0

@ p.kumar Jeneratörü nasıl kullanıyorsunuz? En azından bu şekilde 'list (func (s))' ile bilgisayarımda iyi çalışıyor gibi görünüyor, sonuç 99 öğeyi içeren bir listedir. 'Çizim' hakkında belki de ['matplotlib.pyplot.plot'] 'a bakabilirsiniz (http://matplotlib.org/api/pyplot_api.html). – MSeifert

4

Bir değeri birden çok kez hesaplıyorsunuz ( listesine eklerken ) ve son değeri bir listeye ekleyerek.

Bunun yerine, giderken listeye eklemek istiyoruz.

def func(s): 
    l = [] 
    for i in range(1, 100): 
     l.append(i*2+s*2) 
    return l 

Ayrıca darlığı için gidiyoruz bir list comprehension kullanılarak tek satırda bunu yapabilirsiniz.

func = lambda s: [(t*2)+s*2 for t in range(1, 100)] 

Çıkış:

[22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218] 

Not sonunda 218. Daha önce de söylediğim gibi, sadece son değeri döndürüyordunuz, bu yüzden programınız çıktısı 218.

+4

İhtiyacınız olmayan tek astarlı ısrar etseniz bile, lambda değil, 'def' ile yapmak en iyisidir; “lambda” işlevi, kendi adını bilmez, bu da dekapaj gibi basit şeyleri kırar (bazı durumlarda “çoklu işlem” veya “concurrent.futures” veya hatta “copy.deepcopy” gibi şeylerde gizli olarak yer alır). 'def func (s): geri dönüş aralığı (1, 100) için [(t * 2) + s * 2], aynı şekilde özlü ve daha işlevseldir (ingilizce anlamıyla değil). dil tasarım anlayışı. – ShadowRanger

0

:-) yine göstereceğiz e bol çözüm bu. Farklı kütüphaneler veya jeneratörler ile. Kodunuzda sadece girinti probleminiz vardı ve uçmaya hazırdı. İşte kodunuzdaki küçük değişiklikler.

#In Python3 
def func(s): 
    for i in range(1,100): 
     p = i * 2 + s * 2 
     l.append(p) 
    return l 
l =[] 
print(func(10)) 
İlgili konular