Как перебрать каждый элемент в списке списка в Python? - PullRequest
1 голос
/ 06 июня 2019

У меня есть список элементов, хранящихся в списке в виде списка из списка.Я хочу удалить определенный символ из каждого элемента, если он найден.Я могу сделать это, если я просто использую первый элемент списка.Тем не менее, я получаю «IndexError: список индексов вне диапазона» при использовании цикла for.

Это мой список.

list1 = [['2.6x3.65'],[],['2','2.9x1.7','2.5x1.3']]

Так я поступаю с первым элементом.

if('x' in list1[0][0]):
  rep1 = re.sub('x', ', ', list1[0][0])

Это дает мне вывод в виде 2.6, 3.65 в строковом формате, который я позже смогу преобразовать в float.

Однако, когда я реализую то же самое, используя цикл for, используя следующий код:

 for i in list1[i][i]:
   if('x' in list1[i][i]):
     rep2 = re.sub('x', ', ', list1[i][i])

При использовании цикла for выдает «IndexError: список индексов вне диапазона».

Мой ожидаемый результат - получить следующее:

 list2 = [[2.6, 3.65],[],[2, 2.9, 1.7, 2.5, 1.3]]

Ответы [ 4 ]

3 голосов
/ 06 июня 2019

Вы можете использовать понимание вложенного списка:

list1 = [['2.6x3.65'], [], ['2', '2.9x1.7', '2.5x1.3']]
list2 = [sum([list(map(float, i.split('x'))) for i in l], []) for l in list1]

Вывод:

[[2.6, 3.65], [], [2.0, 2.9, 1.7, 2.5, 1.3]]

Чтобы не смешивать map() с пониманием списка:

list2 = [[float(e) for i in l for e in i.split('x')] for l in list1]
2 голосов
/ 06 июня 2019

Ваш код, вероятно, получает ошибку из-за этой строки:

for i in list1[i][i]:
    ...

Не ясно, каково значение i при оценке list[i][i], но оно не будет работать независимо от того, что вы хотели бы сделать, циклически перебирая свой основной список, а также внутри каждого из его элементов, что также списки. В то время как вы могли бы понять это с помощью явной индексации, Python предлагает вам лучший подход, а именно, циклический просмотр элементов напрямую.

Самое главное, в общем, ваш подход с регулярными выражениями не будет работать, потому что:

re.sub('x', ', ', list1[0][0])

фактически создает строку, которая при печати выглядит идентично тому, как Python печатает список чисел, , но это не список чисел !

Вместо этого вы хотите преобразовать вашу строку в числовой тип. Если все, что вам нужно, это список float с, то просто приведение правильного текстового представления float сделает то же самое, например. float('1.5') == 1.5. То же самое относится и к int, например, int('432') == 432 (но int('1.5') повысит ValueError). Если вы хотите иметь разные объекты для int с и float с, как показывает ожидаемый результат, вы можете сначала попытаться преобразовать в int, а если это не удастся, преобразовать в float:

def to_number(value): 
    try: 
        value = int(value) 
    except ValueError: 
        value = float(value) 
    finally: 
        return value

Имея это в виду, теперь вам нужно убедиться, что ввод этой функции будет строкой с числом. Очевидно, что 1x2 или даже 1, 2 нет, то есть и int('1x2') и int('1, 2') (или с float вместо int) повысится на ValueError. Тем не менее, Python предлагает простой способ синтаксического анализа (ну, разделения) этой строки таким образом, что вы получите '1' и '2' в списке:

'1x2'.split('x') == ['1', '2']

Это также имеет довольно мягкое поведение, заключающееся в изящном создании согласованного вывода, даже если вы применяете это к тексту, не содержащему char для разделения, например ::

'1'.split('x') == ['1']

Со всеми этими строительными блоками теперь можно найти разумное решение (с интенсивным использованием списочных представлений):

list2 = [
    [to_number(x) for elem in inner_list for x in elem.split('x')]
    for inner_list in list1]

print(list2)
# [[2.6, 3.65], [], [2, 2.9, 1.7, 2.5, 1.3]]

( РЕДАКТИРОВАТЬ : добавили ряд объяснений и полностью написали код в виде списочных пониманий).

1 голос
/ 06 июня 2019

Это один подход с использованием ast и itertools.chain.

Ex:

from itertools import chain
import ast

list1 = [['2.6x3.65'],[],['2','2.9x1.7','2.5x1.3']]
result = []

for i in list1:
    temp = []
    for j in i:
        temp.append(map(ast.literal_eval, j.split("x")))
    result.append(list(chain.from_iterable(temp)))

print(result)

Выход:

[[2.6, 3.65], [], [2, 2.9, 1.7, 2.5, 1.3]]
1 голос
/ 06 июня 2019

Один из подходов - перебрать ваш список и добавить новый:

list1 = [['2.6x3.65'],[],['2','2.9x1.7','2.5x1.3']]
new_l = []
for l in list1:
     temp = []
     for elem in l:
         new_s = elem.split("x")
         temp.extend([float(x) for x in new_s])
     new_l.append(temp)


print(new_l)
# [[2.6, 3.65], [], [2.0, 2.9, 1.7, 2.5, 1.3]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...