Отфильтровать список списков кортежей

У меня есть список списков кортежей:

oldList = [[(1,None),(2,45),(3,67)],[(1,None), (2,None), (3,None),(4,56),(5,78)],[(1, None),(2, 98)]] 

Я хотел бы отфильтровать любой экземпляр «None»:

 newList = [[(2,45),(3,67)], [(4,56),(5,78)], [(2, 98)]] 

Ближайший я пришел с этим циклом, но он не отбрасывает весь набор (только «Нет»), а также уничтожает список списков кортежей:

 newList = [] for data in oldList: for point in data: newList.append(filter(None,point)) 

5 Solutions collect form web for “Отфильтровать список списков кортежей”

Самый короткий способ сделать это – с учетом вложенного списка:

 >>> newList = [[t for t in l if None not in t] for l in oldList] >>> newList [[(2, 45), (3, 67)], [(4, 56), (5, 78)], [(2, 98)]] 

Вам нужно вложить два списка, потому что вы имеете дело со списком списков. Внешняя часть понимания списка [[...] for l in oldList] позаботится об итерировании через внешний список для каждого внутреннего списка. Затем во внутреннем понимании списка вы имеете [t for t in l if None not in t] , что довольно простой способ сказать, что вы хотите, чтобы каждый кортеж в списке не содержал None .

(Возможно, вы должны выбрать лучшие имена, чем l и t , но это будет зависеть от вашего проблемного домена. Я выбрал однобуквенные имена, чтобы лучше выделить структуру кода.)

Если вы незнакомы или неудобны в понимании списков, это логически эквивалентно следующему:

 >>> newList = [] >>> for l in oldList: ... temp = [] ... for t in l: ... if None not in t: ... temp.append(t) ... newList.append(temp) ... >>> newList [[(2, 45), (3, 67)], [(4, 56), (5, 78)], [(2, 98)]] 

Вам нужно создать список временных списков внутри вас for цикла для поддержки вложенной структуры списка как:

 >>> new_list = [] >>> for sub_list in oldList: ... temp_list = [] ... for item in sub_list: ... if item[1] is not None: ... temp_list.append(item) ... new_list.append(temp_list) ... >>> new_list [[(2, 45), (3, 67)], [(4, 56), (5, 78)], [(2, 98)]] 

Альтернативно, лучший способ добиться того же – использовать выражение для выражения списка как:

 >>> oldList = [[(1,None),(2,45),(3,67)],[(1,None), (2,None), (3,None),(4,56),(5,78)],[(1, None),(2, 98)]] >>> [[(k, v) for k, v in sub_list if v is not None ] for sub_list in oldList] [[(2, 45), (3, 67)], [(4, 56), (5, 78)], [(2, 98)]] 

Кортеж неизменен, поэтому вы не можете их модифицировать. Вы должны их заменить. Безусловно, самый канонический способ сделать это – использовать понимание списка Python:

 >>> oldList = [[(1,None),(2,45),(3,67)],[(1,None), (2,None), (3,None),(4,56),(5,78)],[(1, None),(2, 98)]] >>> [[tup for tup in sublist if not None in tup] for sublist in oldList] [[(2, 45), (3, 67)], [(4, 56), (5, 78)], [(2, 98)]] >>> 

Перечни:

 >>> newList = [[x for x in lst if None not in x] for lst in oldList] >>> newList [[(2, 45), (3, 67)], [(4, 56), (5, 78)], [(2, 98)]] >>> 

Почему бы просто не добавить блок if чтобы проверить, существует ли первый элемент в вашей point кортежа или есть True . Вы также можете использовать понимание списка, но я предполагаю, что вы новичок в python.

 oldList = [[(1,None),(2,45),(3,67)],[(1,None), (2,None), (3,None),(4,56),(5,78)],[(1, None),(2, 98)]] newList = [] for data in oldList: tempList = [] for point in data: if point[1]: tempList.append(point) newList.append(tempList) print newList >>> [[(2, 45), (3, 67)], [(4, 56), (5, 78)], [(2, 98)]] 
    Python - лучший язык программирования в мире.