简体   繁体   English

Python嵌套for循环:我在做什么错?

[英]Python nested for loop: what am I doing wrong?

I am working with data pulled from a spreadsheet-like file. 我正在处理从类似电子表格的文件中提取的数据。 I am trying to find, for each "ligand", the item with the lowest corresponding "energy". 我试图为每个“配体”找到对应的“能量”最低的项目。 To do this I'm trying to make a list of all the ligands I find in the file, and compare them to one another, using the index value to find the energy of each ligand, keeping the one with the lowest energy. 为此,我尝试列出我在文件中找到的所有配体的列表,并将它们相互比较,使用索引值找到每个配体的能量,并保持能量最低。 However, the following loop is not working out for me. 但是,以下循环对我而言不起作用。 The program won't finish, it just keeps running until I cancel it manually. 该程序不会完成,它会一直运行直到我手动取消它。 I'm assuming this is due to an error in the structure of my loop. 我假设这是由于循环结构中的错误引起的。

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))

As you can see, I've created a separate ligandList containing the ligands, and am using the current index of that list to access the energy values in the lineList. 如您所见,我创建了一个包含配体的单独的配体列表,并且正在使用该列表的当前索引来访问lineList中的能量值。

Does anyone know why this isn't working? 有人知道为什么这行不通吗?

It is a bit hard to answer without some actual data to play with, but I hope this works, or at least leads you into the right direction: 没有一些实际数据可玩,这很难回答,但是我希望这能奏效,或者至少可以引导您朝正确的方向前进:

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]

You look like you're trying to find the element in ligandList with the smallest value in index 42. Let's just do that.... 您似乎正在尝试在索引值为42的配体列表中ligandList具有最小值的元素。

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

If these "Ligands" are something you use regularly, STRONGLY consider writing a class wrapper for them, something like: 如果这些“配体”是您经常使用的东西,则强烈考虑为它们编写一个类包装器,例如:

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...

In which case you can simply create a list of the Ligands: 在这种情况下,您只需创建一个配体列表:

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

and return the object with the smallest energy: 并返回能量最小的对象:

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

As a huge aside, PEP 8 encourages the use of the lowercase naming convention for variables, rather than mixedCase as many languages use. 除了一个很大的方面, PEP 8鼓励对变量使用lowercase命名约定,而不是像许多语言所使用的mixedCase

That's a really inefficient way of doing things. 这是一种非常低效的处理方式。 Lots of index calls. 很多index调用。 It might just feel infinite because it's slow. 它可能会感觉很无限,因为它很慢。

Zip your related things together: 将您的相关内容压缩在一起:

l = zip(ligandList, lineList)

Sort them by “ligand” and “energy”: 按“配体”和“能量”对它们进行排序:

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

Grab the first (lowest) “energy” for each: 抓住每个(最低)的“能量”:

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

Yay. 好极了。

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]
))

It would probably look more flattering if you made lineList contain classes of some kind. 如果使lineList包含某种类,它看起来可能会更讨人喜欢。

Demo 演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM