2014-01-21 20 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