Как объединить массив с его элементами массива в Python?

У меня есть массив, как показано ниже;

constants = ['(1,2)', '(1,5,1)', '1']

Я хотел бы преобразовать массив как показано ниже;

constants = [(1,2), 1, 2, 3, 4, 5, 1]

Для этого я попробовал несколько операций;

from ast import literal_eval
import numpy as np
constants = literal_eval(str(constants).replace("'",""))
constants = [(np.arange(*i) if len(i)==3 else i) if isinstance(i, tuple) else i for i in constants]

И выход был;

constants = [(1, 2), array([1, 2, 3, 4]), 1]

Так что это не ожидаемый результат, и я застрял на этом этапе. Вопрос в том, как я могу объединить массив с его родительским массивом?

почему не преобразован первый кортеж?

Ma0 10.08.2018 13:49

Мне не нужно его преобразовывать. Мне нужно преобразовать кортежи в 3 значения.

Ceylan B. 10.08.2018 13:50

np.arange(1,5,1) не возвращает np.array([1, 2, 3, 4])?

taras 10.08.2018 13:51

@taras Да, это так. Но это не моя проблема. Проблема в том, как объединить его с родительским массивом.

Ceylan B. 10.08.2018 13:52
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
4
206
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

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

from ast import literal_eval


constants = ['(1,2)', '(1,5,1)', '1']
processed = []

for index, c in enumerate(constants):
    parsed = literal_eval(c)
    if isinstance(parsed, (tuple, list)) and index != 0:
        processed.extend(range(1, max(parsed) + 1))
    else:
        processed.append(parsed)

print processed  # [(1, 2), 1, 2, 3, 4, 5, 1]

TypeError: isinstance ожидает 2 аргумента, получено 3

Ceylan B. 10.08.2018 13:54

Результат мне не понравился. Результат должен быть; [(1,2), 1, 2, 3, 4, 5, 1]

Ceylan B. 10.08.2018 13:56

@AndriyIvaneyko, а что, если кортеж не является первым элементом списка?

taras 10.08.2018 14:00

Элемент @taras будет добавлен.

Andriy Ivaneyko 10.08.2018 14:02

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

constants = ['(a, b)', '(x, y, z)', 'i']

в это:

transformed = [(a,b), x, x+z, x+2*z, ..., y, i]

таким образом, что второй кортеж представляет собой диапазон от x до y с шагом z. Итак, ваш окончательный преобразованный массив - это первый элемент, затем диапазон, определенный вашим вторым элементом, а затем ваш последний элемент. Самый простой способ сделать это - просто пошагово:

constants = ['(a, b)', '(x, y, z)', 'i']
literals = [eval(k) for k in constants]    # get rid of the strings
part1 = [literals[0]]                      # individually make each of the three parts of your list
part2 = [k for k in range(literals[1][0], literals[1][1] + 1, literals[1][2])]    # or if you don't need to include y then you could just do range(literals[1])
part3 = [literals[2]]
transformed = part1 + part2 + part3

Предлагаю следующее:

res = []
for cst in constants:

    if isinstance(cst,tuple) and (len(cst) == 3):
        #add the range to the list
        res.extend(range(cst[0],cst[1], cst[2]))
    else:
        res.append(cst)

res дает желаемый результат. Может быть более элегантный способ решить эту проблему.

Ответ принят как подходящий

Это один из подходов.

Демо:

from ast import literal_eval

constants = ['(1,2)', '(1,5,1)', '1']
res = []
for i in constants:                
    val = literal_eval(i)              #Convert to python object
    if isinstance(val, tuple):         #Check if element is tuple
        if len(val) == 3:              #Check if no of elements in tuple == 3
            val = list(val)
            val[1]+=1
            res.extend(range(*val))
            continue            
    res.append(val)
print(res)

Выход:

[(1, 2), 1, 2, 3, 4, 5, 1]

а если массив: constants = ['(1,2)', '(1,5,1)', '1', '(0.1, 0.9, 0.1)']? Ошибка: объект float нельзя интерпретировать как целое число.

Ceylan B. 10.08.2018 14:08

Каков ожидаемый результат ['(1,2)', '(1,5,1)', '1', '(0.1, 0.9, 0.1)']?

Rakesh 10.08.2018 14:09

Ожидаемый результат: [(1,2), 1, 2, 3, 4, 5, 1, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]

Ceylan B. 10.08.2018 14:11

Я решил это; просто замените range(*val) на np.arange(*val).

Ceylan B. 10.08.2018 14:12

Да ... я собирался опубликовать это :)

Rakesh 10.08.2018 14:13

Другие вопросы по теме