2015-11-07 4 views
1

Я пытаюсь отфильтровать список, состоящий из нескольких словарей для бесполезных записей и неидеальных полей. Запись бесполезна, если Mem['visibility'] == "redacted" и затем следует удалить из списка. Запись не идеальна, если любое из полей пуст, и они должны быть заполнены вместо 0 или если Mem['~whatever~'] - это список, и в этом случае список должен быть преобразован в одну строку со всеми объектами в этом списке. Я написал следующий код, чтобы сделать это:Упрощение фильтра списка в Python

class Filter: 

    @staticmethod 
    def members(memberlist): 
     for Mem in memberlist: 
      for Item in Mem: 
       if not Mem[Item]: 
        Mem[Item] = 0 
       if (type(Mem[Item]) is list): 
        Mem[Item] = ', '.join(Mem[Item]) 
      if(Mem['visibility'] == "redacted"): 
       memberlist.remove(Mem) 
     return(memberlist) 

образец: Пользователи

[ 
    {'roles': [], 
    'rank': 'No SCB account', 
    'type': 'main', 
    'stars': 2, 
    'visibility': 'visible', 
    'sid': 'imperium', 
    'handle': 'freakyeagle' 
    }, 
    {'roles': [], 
    'rank': 'Fleet Member', 
    'type': 'main', 
    'stars': 1, 
    'visibility': 'visible', 
    'sid': 'imperium', 
    'handle': 'cadimus'}, 
    {'roles': [], 
    'rank': 'Fleet Member', 
    'type': 'main', 
    'stars': 1, 
    'visibility': 'visible', 
    'sid': 'imperium', 
    'handle': 'belleal'} 
] 

Как я могу сделать это как простой/эффективный, как это возможно?

Кроме того, по какой-то причине, когда я удаляю бесполезный Mem из списка в приведенном выше коде, он прерывает мою вставку в базе данных, которая происходит в следующей функции (член списка в приведенной выше функции эквивалентен члену в этом) :

def member(conn, cursor, member): 
    try: 
     if type(member) is not list: 
      # TODO: Eventually implement single member insert here. 
      print(member) 
     cursor.executemany("INSERT INTO `Citizens` (`Handle`,`Org`,`Role`, " 
          "`Rank`,`Visibility`,`Stars`,`Type`) VALUES " 
          "(%(handle)s,%(sid)s,%(roles)s,%(rank)s," 
          "%(visibility)s,%(stars)s,%(type)s);", member) 
     conn.commit() 

Кто-нибудь знает, почему это происходит?

+2

Как и в сторону, никогда не удалить элементы из списка при переходе по списку - это приведет к непредвиденным результатам по мере пропуска некоторых элементов в списке. – Ben

+0

Какой был бы лучший способ сделать это? Создайте список Mem для удаления и затем удалите его потом? –

+1

Либо перебирайте копию списка ('для mem в memberlist [:]:'), либо добавьте те, которые вы _do_ хотите сохранить в новом списке, и верните это вместо этого. – Ben

ответ

1

Вам не следует удалять элементы из списка, когда вы выполняете итерацию по нему - вы получите непредвиденное поведение, когда элементы будут пропущены после удаления элемента.

Вместо этого сделайте копию списка перебрать:

for mem in memberlist[:]: 
    ... 

Или сохранить результаты, которые вы хотите в другой список и вернуться, что вместо того, чтобы:

keep = [] 
for mem in memberlist: 
    if ...: 
     keep.append(mem) 
return keep 
Смежные вопросы