2014-01-27 5 views
0

Прямо сейчас у меня есть три списка, которые генерируются функцией RE findall, и я пытаюсь удалить некоторые из пустых строк из кортежей внутри списка. И цифры должны быть преобразованы в целое число в процессе тоже:Удалить пустые строки из кортежей внутри списка

Got: [('', '', '1', '1')]

Ожидаемое: [(1, 1)]

Got: [('', '', '20', '500'), ('21', 'failed', '', '')]

Ожидаемое: [(20, 500), (21, 'failed')]

Got: [('3', 'failed', '', ''), ('', '', '48', '23'), ('', '', '96', '0')]

Ожидается: [(3, 'failed'), (48, 23), (96, 0)]

Любые идеи?

+3

Какие Regex вы используете? Почему бы не использовать тот, который не соответствует пустой строке в первую очередь, а не фильтрует ее потом? –

+0

Я старался изо всех сил ... Но я не могу написать другое регулярное выражение ... – user3238319

+1

Ну, может быть, мы сможем вам помочь? –

ответ

3

Как об этом:

def sanitize(t):         
    for i in t: 
     try: 
      yield int(i) 
     except ValueError: 
      yield i 

inputs = [('3', 'failed', '', ''), ('', '', '48', '23'), ('', '', '96', '0')] 
map(tuple, map(sanitize, [filter(None, i) for i in inputs])) 

дает выход:

[(3, 'failed'), (48, 23), (96, 0)] 

filter является функцией, которая действует на последовательности и возвращает только "truthy" элементы. Пустые строки являются ложными. Карта - это еще одна функция, которая принимает последовательность и запускает каждый элемент в этой последовательности через заданную функцию. В этом случае функция sanitize, которая преобразует строку в int, если она может или просто возвращает строку.

Мы используем yield вместо return в функции sanitize как простой способ вернуть еще одну последовательность к следующей функции карты. В качестве альтернативы мы могли бы создать список внутри функции и вернуть ее.

+0

ничего не возвращает ... Может быть, я что-то делаю неправильно? – user3238319

+0

Я тестировал его в оболочке перед отправкой, поэтому он работает. Вы должны будете опубликовать свой фактический код для меня, чтобы сказать, что случилось. Попробуйте удалить слои и выяснить, какой из них не работает. Отлаживать! Используйте консоль Python для такого рода вещей. – aychedee

+0

Просто дважды проверьте, скопировали этот точный код в терминал и запустили его. Работает отлично. Я переформатирую его, чтобы не показывать результат, если хотите. – aychedee

3

вложенного списка понимание с конструктором кортежа:

>>> lst = [('', '', '20', '500'), ('21', 'failed', '', '')] 
>>> [(tuple(int(x) if x.isdigit() else x for x in _ if x)) for _ in lst] 
[(20, 500), (21, 'failed')] 

Для каждого кортежа (_) в lst, построить tuple с выражением генератора. Один конструктор кортежей находится ниже:

tuple(int(x) if x.isdigit() else x for x in _ if x) 

Это кажется смущенным, но я сломаю его. Для каждой строки x в кортеже _ (который является кортежем в lst), постройте кортеж. if x проверяет, не является ли строка пустой. (Если строка x пуста, x является ложной.) if x, выражение генератора будет производить либо x, либо int(x) в зависимости от того, является ли x в вопросе - это цифра в виде строки. (Попытка превратить нечисловую строку в целое число приведет к исключению.)

Для каждого кортежа _ в lst, генератор создает новый, идентичный кортеж, кроме пустых, ложные строки отфильтровываются и любым цифровые строки преобразуются в int с.

Приведенный выше код эквивалентен:

new_lst = [] 

for _ in lst: # For each tuple in lst 
    for x in _: # For each string in tuple 
     temp_tuple =() 
     if x: # Only add to tuple if string is not empty 
      if x.isdigit(): # If x is a digit in string form 
       temp_tuple += (int(x),) # Convert to int 
      else: 
       temp_tuple += (x,) # Keep string 
    new_lst.append(temp_tuple) 
+0

Вы, ребята, хотите немного объяснить? – user3238319

+0

@ пользователь3238319 держись, редактирование. – jayelm

+0

он возвращает [(500,),()] – user3238319

Смежные вопросы