2014-01-21 38 views
0

我正在處理從類似電子表格的文件中提取的數據。我試圖爲每個「配體」找到具有最低對應「能量」的項目。要做到這一點,我試圖列出我在文件中找到的所有配體,並將它們相互比較,使用索引值來查找每個配體的能量,保持能量最低的配體。但是,下面的循環對我來說並不奏效。該程序不會完成,它只是繼續運行,直到我手動取消它。我假設這是由於我的循環結構中有錯誤。python嵌套for循環:我做錯了什麼?

for item in ligandList: 
    for i in ligandList: 
     if ligandList.index(item) != ligandList.index(i): 
      if (item == i) : 
       if float(lineList[ligandList.index(i)][42]) < float(lineList[ligandList.index(item)][42]): 
        lineList.remove(ligandList.index(item)) 
       else: 
        lineList.remove(ligandList.index(i)) 

正如你所看到的,我創建了一個包含了配體獨立ligandList,並正在使用該列表的當前索引來訪問lineList的能量值。

有誰知道這是爲什麼不工作?

+4

縮進的前兩行wwrong –

+0

代替'用於in'項和'的.index(項目)'考慮使用'爲索引,項枚舉(ligandList)'。 – Hyperboreus

+0

對不起,這不是原始代碼,只是傳輸錯誤。 – thephfactor

回答

2

這是一個有點很難沒有一些實際的數據一起玩回答,但我希望這個作品,或至少會將你引入正確的方向:

for idx1, item1 in enumerate(ligandList): 
    for idx2, item2 in enumerate(ligandList): 
     if idx1 == idx2: continue 
     if item1 != item2: continue 
     if float(lineList[idx1][42]) < float(lineList[idx2][42]): 
      del lineList [idx1] 
     else: 
      del lineList [idx2] 
+0

好吧...任何想法,爲什麼我可能會得到一個「列表索引超出範圍」錯誤與此? – thephfactor

+0

因爲'lineList'改變了迭代。 (它變短了) – Hyperboreus

+0

哈哈,是的有意義 – thephfactor

1

你看起來像你想找到在指數42的最小值在ligandList元素讓我們只是做到這一點....

min(ligandList, key=lambda x: float(x[42])) 

如果這些「配體」是你經常使用的東西,儘量考慮寫一個類包裝對他們來說,像:

class Ligand(object): 
    def __init__(self,lst): 
     self.attr_name = lst[index_of_attr] # for each attribute 
     ... # for each attribute 
     ... # etc etc 
     self.energy = lst[42] 
    def __str__(self): 
     """This method defines what the class looks like if you call str() on 
it, e.g. a call to print(Ligand) will show this function's return value.""" 
     return "A Ligand with energy {}".format(self.energy) # or w/e 
    def transmogfiscate(self,other): 
     pass # replace this with whatever Ligands do, if they do things... 

在這種情況下,你可以簡單地創建了配體的列表:

ligands = [Ligand(ligand) for ligand in ligandList] 

,並用最小的能量返回對象:

lil_ligand = min(ligands, key=lambda ligand: ligand.energy) 

是一個巨大的一邊,PEP 8鼓勵許多語言都使用lowercase變量的命名約定,而不是mixedCase

1

這是一種非常低效的做事方式。很多index調用。它可能會感覺無限,因爲它很慢。

郵編你的相關的東西放在一起:

l = zip(ligandList, lineList) 

您可以按照「配體」和「能源」:

l = sorted(l, key=lambda t: (t[0], t[1][42])) 

搶到第一(最低)「能源」爲每個:

l = ((lig, lin[1].next()[1]) for lig, lin in itertools.groupby(l, key=lambda t: t[0])) 

耶。

result = ((lig, lin[1].next()[1]) for lig, lin in itertools.groupby(
    sorted(zip(ligandList, lineList), key=lambda t: (t[0], t[1][42])), 
    lambda t: t[0] 
)) 

它可能看起來更漂亮,如果你做lineList包含某種類。

Demo