2016-03-30 4 views
1

У меня есть список списков кортежей целых чисел.Удалить элемент из списка при условии

ls = [[(a_1, a_2), (b_1, b_2)], [(c_1, c_2), (d_1, d_2), (e_1, e_2)], ...] 

И мне нужно удалить каждый элемент логинсервера, который содержит кортеж которого второй запись равно заданного целое число.

Я попытался это:

for item in ls: 
    for tpl in item: 
     if tpl[1] == m: 
     ls.remove(item) 

Но по какой-то причине, это только удаляет некоторые из элементов списка, но не все, содержащий кортеж второго входа = т.

+0

Вы должны пометить это с помощью языка программирования, который вы используете. Похоже, что ls - это список массивов кортежей, что означает, что вам нужен третий цикл для итерации по массивам. – disperse

ответ

2

используйте список понимание:

ls = [item for item in ls if all(tuple[1] != m for tuple in item)] 

Или использовать фильтр:

ls = filter(lambda item: all(tuple[1] != m for tuple in item),ls) 
+0

Измените 'all' на' any' и '! =' На '=' если это необходимо - я не могу вспомнить, сохраняет ли условие фильтра только те, где функция возвращает 'True ... –

0

Лучший способ для фильтрации списка в Python, чтобы использовать список понимание:

filtered = [item for item in ls if not(contains_m(item))] 

И тогда все, что вам нужно, это функция, которая может сказать, если элемент содержит т, например:

def contains_m(item): 
    return any([tpl[1] == m for tpl in item]) 
0

Удаление itme из списка - не очень хорошая идея, итерации, хотя это.

Попробуйте, что (если где говорит Python здесь)

ls = [[('a_1', 'a_2'), ('b_1', 'b_2')], [('c_1', 'c_2'), ('d_1', 'd_2'), ('e_1', 'e_2')]] 

m='c_2' 
print [ x for x in ls if not [ y for y in x if y[1]==m ]] 
0

Пайтон список итератор ленив. Это означает, что когда вы удаляете элемент из списка, он пропускает следующий элемент. Например, вы хотите, чтобы удалить все те из следующего списка:

[1, 1, 2] 

Ваш for цикл начинается с индекса 0:

[1, 1, 2] 
^ 

Он удаляет элемент и движется дальше:

[1, 2] 
    ^

Этот пример просто поможет проиллюстрировать проблему. Один из простых способов заключается в петле в обратном направлении с помощью индекса:

for ind in range(len(ls)-1, -1, -1): 
    item = ls[ind] 
    for tpl in item: 
     if tpl[1] == m: 
      del ls[ind] 
      break # You can end the inner loop immediately in this case 

Другой способ сделать копию списка перебрать, но удалить из оригинала:

for item in ls[:]: 
    for tpl in item: 
     if tpl[1] == m: 
      ls.remove(item) 
      break 

Последний подход может быть упрощается в создании списка вывода, который содержит только те элементы, которые вы хотите. Это проще всего сделать с пониманием списка. См. @AlexeySmirnov's answer за лучший способ сделать это.

1

Код сосет, и нам нужно меньше его - здесь так же скудно, как и получается.

[l for l in ls if m not in [i[1] for i in l]] 
Смежные вопросы