在for循环期间从Python列表中删除东西

时间:2010-08-04 14:57:19

标签: python list loops

这是我的代码:

toBe =[]
#Check if there is any get request
if request.GET.items() != []:
    for x in DB:

        try:
            #This is removing the PMT that is spcific to the name
            if request.GET['pmtName'] != "None":
                if not request.GET['pmtName'] in x['tags']:
                    print x['title'], x['tags']
                    toBe.append(x)
                    continue

            #This is removing the peak stuff
            if int(request.GET['peakMin']):
                if int(request.GET['peakMin']) < int(x['charge_peak']):
                    toBe.append(x)
                    continue
            if int(request.GET['peakMax']):
                if int(request.GET['peakMax']) > int(x['charge_peak']):
                    toBe.append(x)
                    continue
            if int(request.GET['widthMin']):
                if int(request.GET['widthMin']) < int(x['charge_width']):
                    toBe.append(x)
                    continue
            if int(request.GET['widthMax']):
                if int(request.GET['widthMax']) > int(x['charge_width']):
                    toBe.append(x)
                    continue
        except:
            pass
#TODO: Stupid hack, this needs to be fixed
for x in toBe:
    DB.remove(x)
del toBe

基本上我想删除该项目,然后跳到下一个项目。这个问题是,当发生这种情况时,它会弄乱列表的顺序并跳过一些。有人知道为此工作吗?或者也许只是一种不同的方式呢?

感谢

3 个答案:

答案 0 :(得分:1)

for x in DB[:]:复制了列表DB,因此您可以在修改原始列表时对其进行迭代。护理 - 记忆密集和缓慢。

更好的方法是在列表上创建另一个层,只生成一些值,然后在以后需要时迭代它。你可以用生成器做到这一点:

def db_view( DB ):
    for x in DB:

        #This is removing the PMT that is spcific to the name
        if request.GET.get( 'pmtName', None ) not in x['tags']:
                print x['title'], x['tags']
                continue

        #This is removing the peak stuff
        if int(request.GET['peakMin']):
            if int(request.GET['peakMin']) < int(x['charge_peak']):
                continue

        if int(request.GET['peakMax']):
            if int(request.GET['peakMax']) > int(x['charge_peak']):
                continue

        if int(request.GET['widthMin']):
            if int(request.GET['widthMin']) < int(x['charge_width']):
                continue

        if int(request.GET['widthMax']):
            if int(request.GET['widthMax']) > int(x['charge_width']):
                continue

        yield x

你会使用

for x in db_view( DB ):
    # Do stuff

答案 1 :(得分:0)

我通常会看到这种问题的答案,如果要向后循环列表。以下是我在其中一个程序中的表现:

for i in range(len(my_list)-1,-1,-1):
    # do something

即使我将项目添加到列表中也是如此。在http://desk.stinkpot.org:8080/tricks/index.php/2006/08/read-a-list-backwards-in-python/上,他们说你可以使用语法“for i in list [:: - 1]:”。我没有尝试过这样做。

答案 2 :(得分:0)

对于request.GET的每个值,您正在对x进行相同的插值。相反,您可以构建一次可重复使用的过滤函数列表。

例如:

if request.GET:
    filters = []
    if 'pmtName' in request.GET:
        n = request.GET['pmtName']
        filters.append(lambda x: n not in x['tags'])
    if 'peakMin' in request.GET and request.GET['peakMin'].isdigit():
        n = int(request.GET['peakMin'])
        filters.append(lambda x: n < int(x['charge_peak']))
    if 'peakMax' in request.GET and request.GET['peakMax'].isdigit():
        n = int(request.GET['peakMax'])
        filters.append(lambda x: n > int(x['charge_peak']))
    if 'widthMin' in request.GET and request.GET['widthMin'].isdigit():
        n = int(request.GET['widthMin'])
        filters.append(lambda x: n < int(x['charge_width']))
    if 'widthMax' in request.GET and request.GET['widthMax'].isdigit():
        n = int(request.GET['widthMax'])
        filters.append(lambda x: n > int(x['charge_width']))

然后,您可以应用此功能列表来选择要删除的DB成员:

remove_these = [ x for x in DB if any(f(x) for f in filters)]
for item in remove_these:
    DB.remove(item)

或者创建一个生成器,它将返回所有过滤器失败的DB值:

filtered_DB = ( x for x in DB if all(not f(x) for f in filters))