2010-08-04 4 views
0

Вот мой код:Удаление вещи из списка Python во время цикла для

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 

По существу я хочу, чтобы удалить элемент, а затем перейти к следующему. Проблема заключается в том, что когда это происходит, это забивает порядок списка и пропускает некоторые. Кто-нибудь знает об этом? Или, может быть, это просто другой способ сделать это?

благодаря

ответ

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/ говорят, что вы можете использовать синтаксис «для i в списке [:: - 1]:« вместо этого. Я не пробовал так поступать.

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

Затем вы можете использовать этот список функций для выбора членов БД для удаления:

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

Или создать генератор, который будет возвращать значение DB, что все фильтры не включаются: