Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python成员限制测试?_Python - Fatal编程技术网

Python成员限制测试?

Python成员限制测试?,python,Python,我使用的一种方法有问题,该方法用于测试地理位置列表中的成员资格,并从未通过此检查的预算列表中删除条目。有趣的是,这个方法需要运行3次才能捕获100%的失败条目 budg元素示例: budg = ['KELOG_PSOD_32773 20131125 000327 73144652.3376898.6 9769.50', 'KELOG_PSOD_32774 201

我使用的一种方法有问题,该方法用于测试地理位置列表中的成员资格,并从未通过此检查的预算列表中删除条目。有趣的是,这个方法需要运行3次才能捕获100%的失败条目

budg元素示例:

budg = ['KELOG_PSOD_32773                                  20131125 000327   73144652.3376898.6 9769.50', 'KELOG_PSOD_32774                                  20131125 000327   74140034.3406629.9 4473.90']
geolist = ['KELOG_GEO_32773','KELOG_GEO_32775']

def remove_entry(budg, geolist):
    for e in budg:
        record = 'KELOG_GEO_' + e[11:e.index(' ')]
        if record not in geolist:
            print e
            removed.append(budg.pop(budg.index(e)))
地理元素示例:

budg = ['KELOG_PSOD_32773                                  20131125 000327   73144652.3376898.6 9769.50', 'KELOG_PSOD_32774                                  20131125 000327   74140034.3406629.9 4473.90']
geolist = ['KELOG_GEO_32773','KELOG_GEO_32775']

def remove_entry(budg, geolist):
    for e in budg:
        record = 'KELOG_GEO_' + e[11:e.index(' ')]
        if record not in geolist:
            print e
            removed.append(budg.pop(budg.index(e)))
我对每个列表都有大约2500个条目的列表运行此操作。截至今天,budg列表中存在44个不合格条目。运行此方法一次后,budg列表中始终存在7个误报。然后他们中的4人被抓到再次使用它。最后,在第三次运行中找到剩余的3个。我知道我可以在脚本中运行这个方法3次,然后一天调用一次,但这真的开始困扰我了

我尝试对列表进行反向排序,有趣的是,在第一次尝试时,我提取了44个失败条目中的37个,但其中一些条目将出现在第二次运行结果中,如果我不对列表进行反向排序,则第三次运行结果中也会出现


您是否知道我可能违反此代码对成员资格测试的任何限制?你们中有人以前见过类似列表的行为吗

您正在从
budg
中删除元素,同时在其上循环。执行以下操作时,for循环迭代器的
不会更新其索引:

>>> lst = [1, 2, 3]
>>> for i in lst:
...     print i
...     lst.remove(i)
... 
1
3
这里跳过了
2
,因为迭代器首先处理
lst[0]
,然后移动到
lst[1]
,此时它来自一个包含
[2,3]
的列表,而不是
[1,2,3]

改用
while
循环:

i = 0
while i < len(budg):
    e = budg[i]
    record = 'KELOG_GEO_' + e.split(None, 1)[0][11:]
    if record not in geolist:
        removed.append(budg.pop(i))
    else:
        i += 1
i=0
而我

现在,您可以直接控制正在处理的索引,并且在不删除元素时只增加
i

您不应该在迭代列表时从列表中删除元素。原因是,这会修改要删除的元素的索引,从而更改循环将继续其迭代的位置


您应该先确定要删除哪些元素,然后再删除它们。

问题是您正在更改正在迭代的列表。避免这种情况的方法不止一种。一种简单易懂且快速的方法是创建一个新的列表,去掉您想要删除的项目,然后用它替换原来的列表。我的意思是:

budg = ['KELOG_PSOD_32773                                  20131125 000327   73144652.3376898.6 9769.50',
        'KELOG_PSOD_32774                                  20131125 000327   74140034.3406629.9 4473.90']

geoset = {'KELOG_GEO_32773', 'KELOG_GEO_32775'}  # note this is now a set

def remove_entry(budg, geoset):
    cleaned = []
    for e in budg:
        record = 'KELOG_GEO_' + e[11:e.index(' ')]
        if record in geoset:  # keep it
            cleaned.append(e)
    budg[:] = cleaned

remove_entry(budg, geolist)
print 'budg:', budg
这种方法的另一个优点是,它可以简化为一行代码:

budg = [e for e in budg if 'KELOG_GEO_' + e[11:e.index(' ')] in geoset]

正如在修订后的代码开头的一篇评论中所指出的,我将
geolist
改为
geoset
,因为在
集合中测试成员身份通常比在列表中检查成员身份要快得多(如果列表很大)。

或者在列表中后退而不是前进;然后您可以一次而不是两次完成。您也可以使用
for i in xrange(len(budg)-1,-1,-1):
向后跨过列表,然后您不必使用特殊的处理程序来有条件地修改计数器。@SilasRay:当然,但随后您还必须反转
删除的
,或者在开始时插入。这就足够了。我猜这可以归结为,与budg相比,删除的
是否需要很长时间,哪一个是最好的。