2013-05-03 18 views
13

Bir listedeki tüm verileri bir UDP soketi üzerinden göndermek için tek bir arabelleğe paketlemek istiyorum. Liste nispeten uzun, bu yüzden listedeki her öğeyi indeksleme sıkıcı.Python struct.pack() bir listedeki tek tek öğeler için mi?

NumElements = len(data) 
buf = struct.pack('d'*NumElements,data[0],data[1],data[2],data[3],data[4]) 

Ama bir şey ben listeye başka unsurlar eklendi eğer aramayı değiştirmek ... gibi bir şey gerektirmez daha pythonic yapmak istiyorsunuz:

Bu defa ne var
NumElements = len(data) 
buf = struct.pack('d'*NumElements,data) # Returns error 

Bunu yapmanın iyi bir yolu var mı?

cevap

15

Evet, *args çağrı sözdizimini kullanabilirsiniz. Bunun yerine

:

buf = struct.pack('d'*NumElements,data) # Returns error 

... Bunu yapmak:

buf = struct.pack('d'*NumElements, *data) # Works 

eğitimde Unpacking Argument Lists bakınız. Kısaca (Ama gerçekten, değil, sadece 4.7.4 bölüm 4.7 tümünü okumak ya da "ters bir durum ..." ... atıfta olup bittiğini bilmek olmaz):

... argümanlar bir zaten zaman liste veya tuple ancak ayrı konumsal argümanlar gerektiren bir işlev çağrısı için paketin açılması gerekir… argümanları listeden çıkartmak için * -operator ile işlev çağrısını yazınız veya tuple…

+0

Ah, ihtiyacım olan şey budur! Teşekkür ederim! – user1636547

+1

'd '* NumElements' çok iyi bir uygulama değil, yalnızca ayrıştırmak için harcayacağı çok büyük bir dizi oluşturabilir, yalnızca sonradan serbest kalır. Bunun yerine sayıyı doğrudan dizeye ekleyin: 'buf = struct.pack (" {0: d} d ".format (NumElements), * data)' – ideasman42

+0

@ ideasman42: İyi nokta. Ancak çok sayıda değerle, 500000 argümanına dönüştürmek, 'd' * 500000 geçmenin bir problemi kadar olabilir, bu yüzden bunu 'b' 'ye karşı test etmek isteyebilirsiniz. Join (struct.pack (' d ') , elem) elem için veri) 'ya da' struct' yerine 'array' veya' ctypes' gibi bir şeyi kullanmayı düşün. – abarnert