2013-08-25 20 views
7

Python3'te map kullanmayı deniyorum. İşte kullanıyorum bazı kod: AncakPython3'te haritanın tembel olmayan değerlendirme sürümü?

import csv 

data = [ 
    [1], 
    [2], 
    [3] 
] 

with open("output.csv", "w") as f: 
    writer = csv.writer(f) 
    map(writer.writerow, data) 

, Python3 içinde map bir yineleyici döndürür beri, bu kod Python3 çalışmıyor

(ancak map bu sürümü beri Python2 içinde çalışıyor hep list dönüş)

Geçerli çözümüm, değerlendirmeyi zorlamak için yineleyici üzerinden bir list işlev çağrısı eklemektir. Ama garip görünüyor (Geri dönüş değeri umurumda değil, niçin yineleyiciyi bir listeye dönüştürmeliyim?)

Daha iyi çözümler?

+3

'map' yan etkilerin kullanılması garip olan şeydir. Python 2 'map' de dönüş değerlerini toplar. Yeni davranış sadece daha fazla vurgulamaktadır. Sadece bunu yapma, [for döngüsünü kullan] (http://stackoverflow.com/q/5753597/395760). – delnan

+0

@delnan Bağlantı için teşekkürler, aslında yan etki için 'map' kullanmamalıyım. Python 3 için – yegle

+1

, 'liste (harita (lambda x: 2 * x, [1,2,3]))' –

cevap

14

Yan etkileri (örneğin işlev çağrısı) için Python2.x içinde bile iade edilen değerler ile ilgilenmiyorsanız, bunun için map'u kullanın. Bu işlev None döndürür, ancak bir milyon kez yinelerse - atmak için bir milyon None s listesi oluşturuyordunuz. csv modül izin verdiği kullanımı

for row in data: 
    writer.writerow(row) 

ya:

writer.writerows(data) 

nedense gerçekten, gerçekten kullanmak istedi Eğer doğru yolu için-döngü ve aramak ya olduğu map, daha sonra itertools gelen consume tarifi kullanımı ve sıfır uzunlukta deque, örneğin oluşturabilir:

from collections import deque 
deque(map(writer.writerow, data), maxlen=0) 
2

Dönüş değeriyle ilgilenmezseniz, map iş için en iyi araç değildir. Basit for daha iyi olurdu:

for d in data: 
    writer.writerow(d) 

Yani Python 2.x ve 3.x iyi iş olacak Yeni bir liste oluşturmak istediğinizde map'un yararlı olduğuna dikkat edin, yalnızca etki için yinelenebilir bir şekilde geçiş yapıyorsanız, for kullanın.

2

Bunu yapmak için bir zero length deque ayarlayabilirsiniz:

with open("output.csv", "w") as f: 
    writer = csv.writer(f) 
    collections.deque(map(writer.writerow, data),0) 

Bu itertools.consume (yineleyici, Yok) tarifi çalıştığını aynı yoldur. İşlevsel olarak listeyi oluşturmadan yineleyiciyi tüketir.

Ayrıca, consume recipe itertools'tan da kullanabilirsiniz.

Ancak bir döngü daha okunabilir ve bana Pythonic, ancak YMMV.