在子列表中查找值,并使用其元素值减去前一个元素值

时间:2013-11-14 14:49:56

标签: python

我想在列表列表中找到一条记录,在这种情况下是3并得到 其元素[2]与其先前记录中的元素[2]的减法

mylist = [
["acc", 2, 3.1,4.3,"pe"],
["fir", 1, 3.5,5.2,"p1"],
["sec", 3, 1.1,5.8,"pe"],
["set", 5, 6.2,6,2,"pa"],
["eve", 8, 5.4,5.7,"io"], 
["ewa", 3, 4.1,4.1,"po"]
]

结果应该是:

3.5 - 1.1和5.2 - 5.8
5.4 - 4.1和5.7 - 4.1


我可以通过这段代码得到它,但是我想学习一些更好更简单的方法,谢谢。

i=0    
while i<len(mylist)-1:
        if mylist[i][1] == 3:
            print mylist[i-1][2]-mylist[i][2]
            print mylist[i-1][3]-mylist[i][3]
        i+=1

3 个答案:

答案 0 :(得分:1)

您可以使用for循环来代替使用while循环。

for row1, row2 in zip(mylist[1:], mylist[0:-1]):
    if row1[1] == 3:
        print [y - x for x, y in zip(row1[2:4], row2[2:4])]

您还可以使用izip方法而不是zip方法来节省一些内存。

from itertools import izip

for row1, row2 in izip(mylist[1:], mylist[0:-1]):
    if row1[1] == 3:
        print [y - x for x, y in izip(row1[2:4], row2[2:4])]

这些代码段将输出

[2.4, -0.6]
[1.3, 1.6]

izip()使用generators代替列表。这可能会提高脚本的性能,并可以节省内存。

如果您更喜欢上述代码的较短版本,则可以使用列表推导。

from itertools import izip
print [[y - x for x, y in izip(row1[2:4], row2[2:4])] for row1, row2 in izip(mylist[1:], mylist[:-1]) if row1[1] == 3]

输出:

[[2.4, -0.6], [1.3, 1.6]]

您也可以制作上述

的生成器
for val in ([y - x for x, y in zip(row1[2:4], row2[2:4])] for row1, row2 in zip(mylist[1:], mylist[:-1]) if row1[1] == 3):
    print val

输出:

[2.4, -0.6]
[1.3, 1.6]

请记住,通过执行此操作,在您访问最后一项后,生成器已耗尽,因此如果您需要存储输出的值,则不应使用生成器。

答案 1 :(得分:0)

您可以使用生成器保存合格索引,并在后续步骤中使用生成器,如此

gen = (x for x, y in enumerate(mylist) if y[1] == 3)
[(mylist[x-1][2] - mylist[x][2], mylist[x-1][3] - mylist[x][3]) for x in gen]
[(2.4, -0.5999999999999996), (1.3000000000000007, 1.6000000000000005)]

答案 2 :(得分:0)

简短回答

for previous, current in zip(mylist[:-1], mylist[1:]):
    if current[1] == 3:
        print previous[2] - current[2]
        print previous[3] - current[3]

长答案

我正在做的是在没有第一个元素和没有最后一个元素的列表的情况下压缩列表:

>>> z = [10, 20, 30, 40, 50]
>>> z[:-1]
[10, 20, 30, 40]
>>> z[1:]
[20, 30, 40, 50]
>>> zip(z[:-1], z[1:])
[(10, 20), (20, 30), (30, 40), (40, 50)]

通过遍历压缩列表,我们可以依次访问前一个项目和当前项目,这可以通过我在for循环中给出变量的名称来清楚。

请注意,我的解决方案可以正确处理列表中有零个或一个项目的情况。发生这种情况时,压缩列表为空,因此for循环不执行任何操作。