2016-03-27 26 views
0

iç içe geçmiş bir listenin eşit olmayan uzunlukta çok sayıda eleman benzerlik hesaplanması olan değişen uzunluklarda:her iki elemanı, bir iç içe listesi

lst = [[a,bcbcbcbcbc],[e,bbccbbccb],[i,ccbbccbb],[o,cbbccbb]] 

My çıkışı, bu görünüm dataframe bir csv'dir:

comparison  similarity_score 
    a:e   *some score  
    a:i   *some score 
    a:o   *some score 
    e:i   *some score 
    e:o   *some score 
    i:o   *some score 

kodum: ancak bir hata recieving am

similarity = [] 
for i in lst: 
    name = i[0] 
    string = i[1] 
    score = 0.0 
    length =(len(string)) 
    for i in range(length): 
     if string[i]==string[i+1]: 
      score += 1.0 
    new_score = (100.0*score)/length 
    name_seq = name[i] + ':' + name[i+1] 
    similarity.append(name_seq,new_score) 

similarity.pdDataFrame(similarity, columns = ['comparison' , 'similarity_score']) 
similarity.to_csv('similarity_score.csv') 

:

if codes[i]==codes[i+1]: 
      IndexError: string index out of range 

herhangi bir tavsiye ? Teşekkürler! Python'un belgelerine range göre

+0

Numpadler nerede başlatılır? kodları [i] == kodları [i + 1], kod snippet'inizde görünmüyorsa, dize [i] == string [i + 1] – elhefe

+0

'numPlaces' nedir (belki de uzunluk olması gerekiyordu) ')? Özel durumunuzdaki satır neden gösterdiğiniz koddaki satırlardan hiçbiriyle eşleşmiyor? Her neyse, sanırım sen benim kafamı karıştırıyorsun çünkü ben farklı zamanlarda iki farklı şey için aynı değişken adını kullanıyorsun. Ve eğer 'isim' listenizde 'isim' ise, yaptığınız yer [i + 1] '' hiç bir anlam ifade etmiyor. – Blckknght

+0

@Blckknght, düzeltmeler için teşekkür ederiz. İtiraf etmeliyim ki, i döngülerinde oldukça kafam karıştı. –

cevap

1

örnekle şunları yapar:

Kodunuzda

>>>range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

(varsayarak değişken isimleri değişmedi): Bir giriş bcb verilen başka deyişle

... 
length =(len(string))   # For an input of 'bcb' length will be 3 
for i in range(length):   # For an input of 'bcb' range will be [0, 1, 2] 
    if string[i]==string[i+1]: # When i == 2 i + 1 == 3 which gives you the 
           # IndexError: string index out of range 
... 

, if ifadeniz aşağıdaki indislere bakacaktır:

(0, 1)
(1, 2)
(2, 3) <-- Bu durumda 3 sorununuz. Görmek istediğiniz gibi

En büyük sorunu üst seviyede sadece bir defada bir name,string çifti yineleme olduğunuzu düşünüyorum [0, len(string) - 1]

1

den name,string çifti, bir çift Sorununuz iterate düzeltmek için Çıktınızda (eşleştirilmiş isimlerle gösterildiği gibi a:e).

name ve string değerlerini daha sonra dizine eklemeyi deniyorsunuz, ancak bunu yapmak istediğiniz şeyi elde etmiyor (bir dizgiyi hesaplamak için birbirine iki dizeyi karşılaştırıyor), çünkü yalnızca bitişik karakterlere erişiyorsunuz. aynı dize. Aldığınız istisna, i+1 dizesinin sonundan çıkabilir. İç döngüdeki hem de dış döngüden alınan öğeler için (name, string çiftleri) i'u kullandığınız için daha fazla karışıklık var.

, ben itertools.combinations kullanmanızı öneririz çiftleri çiftleri almak için:
import itertools 

for [name1, string1], [name2, string2] in itertools.combinations(lst, 2): 

Şimdi döngü geri kalanında iki isim ve iki dize değişkenleri kullanabilirsiniz.

Sana birbirlerine aynı uzunlukta değiliz çünkü puanınızı almak için dizeleri karşılaştırmak istediğiniz anlamak tamamen emin değilim. Dizelerin yalnızca başlangıç ​​parçalarını karşılaştırmak istiyorsanız (ve uzun olanın bitini dikkate almazsanız), iki dizge arasında karşılık gelen karakter çiftlerini almak için zip'u kullanabilirsiniz. Daha sonra bir jeneratör ifadesinde bunları karşılaştırmak ve bool sonuçları (True tamsayı özel bir sürümüdür 1 ve False0 bir sürümüdür) ekleyebilirsiniz.(Eğer uzunluk farklılıkları cezalandırmak istiyorsanız ya da belki daha büyük) Daha sonra dize ait küçük olanını tarafından bölebilirsiniz:

common_letters = sum(c1 == c2 for c1, c2 in zip(string1, string2)) 
new_score = common_letters * 100/min(len(string1), len(string2)) 

bir daha bariz sorun var, iki argümanlarla append aradıklarını nerede. Eğer gerçekten 2-tuple eklemek istiyorsanız, ekstra bir parantez setine ihtiyacınız var:

similarity.append((name_seq, new_score))