2016-03-31 30 views
3

Planladığım bir nesneyi oluşturmak için bu dosyalardan vişne almak için bir dizi açılmış dosyayı ayrıştırmak üzere bir dizi jeneratör oluşturmak üzere Python 3.5 kullanıyorum daha sonra ihraç etmek. Orijinal olarak her dosyanın bütünüyle ayrışıyor ve herhangi bir analiz yapmadan önce bir sözlük nesnesi listesi oluşturuyordum, ancak bu işlem bazen 30 saniyeye kadar çıkabiliyordu ve sadece her bir satırın her satırında yalnızca bir kez çalışmam gerektiğinden Jeneratör kullanmak için harika bir fırsat. Bununla birlikte, kavramsal olarak bir şeyleri jeneratörlerle ve belki de bir jeneratör içindeki nesnelerin mutabilitesiyle özlediğimi hissediyorum.Python Generator İfadelerinin Muhtemelen Liste ve Sözlük Anlaşılırlığının Mutability: İç içe Sözlük Sözlük Tuhaflık

parsers = {} 
# iterate over files in the file_name file to get their attributes 
for dataset, data_file in files.items(): 
    # Store each dataset as a list of dictionaries with keys that 
    # correspond to the attributes of that dataset 
    parsers[dataset] = [{attributes[dataset][i]: value.strip('~') 
         for i, value in enumerate(line.strip().split('^'))} 
         for line 
         in data_file] 

Ve arayarak listesine erişebilir: şu şekildedir: sözlükleri bir listesini yapar

Benim orijinal kod gider

>>>parsers['definitions'] 

Ve sözlükler bir listesini dönen beklendiği gibi çalışır . Ancak bu listeyi bir jeneratöre dönüştürdüğümde, her çeşit gariplik olur.

parsers = {} 
# iterate over files in the file_name file to get their attributes 
for dataset, data_file in files.items(): 
    # Store each dataset as a list of dictionaries with keys that 
    # correspond to the attributes of that dataset 
    parsers[dataset] = ({attributes[dataset][i]: value.strip('~') 
         for i, value in enumerate(line.strip().split('^'))} 
         for line 
         in data_file) 

Ve kullanarak çağrı:

>>> next(parsers['definitions']) 

Bu kod çalıştırma aralığı hata bir dizin döndürür.

İki kod bölümü arasında görebildiğim en önemli fark, liste anlaması sürümünde, python'un listeyi dosyadan oluşturması ve anlama değişkenlerini daha sonra kullanmak üzere saklamak zorunda kalmadan devam etmesidir. Tersine, jeneratör ifadesinde, jeneratörü içinde tanımlanmış olan değişkenler, jeneratörün her bir sonraki çağrısını kodumda daha sonra etkiledikleri için, jeneratörle birlikte depolanması gerekir. Jeneratörün içindeki değişkenlerin belki de kodumun oluşturduğu diğer jeneratörler ile bir isim alanını paylaştığını düşünüyorum ve bu nedenle her jeneratörün en son hangi jenerasyon ifadesinin çalıştırıldığına bağlı olarak değişken davranışı vardır ve bu nedenle değişkenlerin değerlerini en son olarak ayarlar.

Bu sorunun nedeni ile ilgili herhangi bir düşünceyi takdir ediyorum!

+0

Tam izini kaydeder misiniz? Bu yardımcı olabilir. . . – mgilson

cevap

3

Sorunun sözlükleri oluştururken olduğunu varsayalım. Liste sürümü ile, datasetfor döngünün belirli fırsatta ne idiyse dataset olduğunu

attributes[dataset][i] 

Not. sonra döngü tamamladı Ancak, jeneratör ile, bu ifade kadar değerlendirilmez, bu nedenle dataset

İşte süper basit demo ... files.items() döngüden son veri kümesinin değeri olur o umarım problem üzerinde durmaktadır: biz jeneratörden değerlerini alırken, a değeri 3 çünkü biz her zaman [3, 3, 3] olsun

results = [] 
for a in [1, 2, 3]: 
    results.append(a for _ in range(3)) 

for r in results: 
    print(list(r)) 

Not.

+0

İşte bu kadar!Yardım için teşekkürler, sağlanan demo, başımı sorun etrafında sarmak için çok yardımcı oldu. Bazen her bir sözlüğü doğru bir şekilde gösterecek tutarsız davranışlar elde ettim çünkü bir sözlük üzerinde yineleniyordum ve bu yüzden jeneratörlerim yeterince uzun bir öznitelik listesi son öğe olarak çağrıldığında çalışacaktı (sözlükler sipariş edilmiyor). Ayrıca, tercümanın dışında kullanılan alt çizgiyi daha önce hiç görmedim, bunu gelecekte uzayda tasarruf etmek için kullanmaya çalışabilirim, teşekkür ederim. – CameronCairns