2017-02-21 20 views
3

У меня есть структурированный список списков, в которых каждый элемент является строкой. Я хочу преобразовать определенные (известные индексы, всегда одни и те же) элементы в этот список списков в целые числа. Я попытался использовать понимание списка или метод isdigit() (нет отрицательных элементов), но он не может понять это.Преобразование определенных элементов в список списков из строки в целое число

list_of_lists = [['spam','1','toast'], ['bacon','5','eggs'], ['juice', '8', 'tea']] 
new_breakfast_list = [[int(element) for element in row] for row in list_of_lists] 

Приведенный выше код понятным дает ValueError: invalid literal for int() with base 10: 'spam' при попытке преобразования первого элемента. Я хочу, либо игнорировать ошибку и двигаться вперед к следующему элементу или, может быть, в частности, петлю на что-то вроде list_of_lists[i][1], так что я могу получить:

print(new_breakfast_list) 
[['spam', 1, 'toast'], ['bacon', 5, 'eggs'], ['juice', 8, 'tea']] 
+1

Как насчет использования списка словарей вместо списка списков? Ваши внутренние элементы кажутся структурированными, что было бы более подходящим для использования словаря или даже создания класса. – danielunderwood

+1

Является ли элемент, который вы хотите конвертировать, всегда в том же положении для каждого списка? – nloewen

+0

Да, использование класса или словаря, вероятно, будет более подходящим. – codymccodeface

ответ

4

Ваш список понимание почти правильно, вам просто нужно проверить с помощью isdigit() во внутреннем цикле, и использовать int(element) или просто element в зависимости от значения, если isdigit.

new_breakfast_list = [[int(element) for element in row if element.isdigit() else element] for row in list_of_lists] 

В качестве альтернативы, как вы знаете, целые элементы встречаются в индексе 1, вы можете использовать:

for element in list_of_lists: 
    element[1]=int(element[1]) 

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

+0

Согласитесь с этим: если вы точно знаете, что каждый внутренний список имеет 3 элемента, то зачем их перебирать ... просто проиндексируйте их. (Может быть, это не Pythonic?) –

+0

Цикл 'for' - это, возможно, самый простой способ сделать это. Не каждая проблема должна решаться с учетом списка. –

+0

Я был смущен тем, что для вызова правильного элемента мне понадобился двузначный индекс, например. 'print (list_of_lists [1])' дает '['bacon', 5, 'eggs']' not '5'. Если вы пишете его как 'для строки в list_of_lists:' \ n 'row [1] = int (строка [1])', это имеет для меня больше смысла. Большое спасибо за помощь! – codymccodeface

1

Просто определить свою собственную функцию маленького помощника, что-то простое, как:

def maybe_int(val): 
    try: 
     return int(val) 
    except ValueError: 
     return val 

Теперь вы можете использовать это в любом понимании, которое вы хотите. Он будет продолжать работать в некоторых случаях, когда проверка str.isdigit не выполняется (например, пробелы в строке, отрицательные числа и т. Д.).

Если структура данных надежная, не беспокойтесь об этом материале. Просто сделать простой список-Комп:

>>> [[x, int(n), y] for x, n, y in list_of_lists] 
[['spam', 1, 'toast'], ['bacon', 5, 'eggs'], ['juice', 8, 'tea']] 
+0

вы должны повторно добавить часть о отрицательных числах. Большинство людей упускают из виду эту часть, и ваша функция выглядит громоздкой. –

+0

ОК, добавили его обратно. – wim

+0

, и ваш listcomp хорош, так как он не пытается конвертировать другие элементы. –

2

, так как вы имеете дело с положительными целыми числами вы можете проверить, если строка имеет только цифры в нем и преобразовать или нет с помощью трехкомпонентной.

list_of_lists = [['spam','1','toast'], ['bacon','5','eggs'], ['juice', '8', 'tea']] 
new_breakfast_list = [[int(element) if element.isdigit() else element for element in row] for row in list_of_lists] 

выходы:

[['spam', 1, 'toast'], ['bacon', 5, 'eggs'], ['juice', 8, 'tea']] 

2 отрицательные стороны, хотя:

  • пытается преобразовать все элементы, даже если только один второй является целым числом
  • она не работает (если они вам понадобятся)

примечание: есть громоздкий/не очень эффективный способ справиться с общим положительным/отрицательным/начинающимся с целого целого случая, используйте его только в этом, вам нужно! в противном случае Wim ответ с try/except лучше

new_breakfast_list = [[int(element) if element.strip().isdigit() or (element.strip()[0]=="-" and element.strip()[1:].isdigit()) else element for element in row] for row in list_of_lists] 
+0

'isdigit' - это плохой способ проверить, будет ли работать' int (element) '. – wim

+0

согласился, но в этом случае вы имеете дело с количеством элементов, которые не могут быть отрицательными, или я бы не ответил на это. –

+0

ОК, я пропустил это. Удалено нисходящее. – wim