Как создать строку комбинаций массивов с учетом списка строк «исходного кода»? - PullRequest
0 голосов
/ 01 декабря 2018

По сути, мне дан список строк, таких как:

["structA.structB.myArr[6].myVar",
"structB.myArr1[4].myArr2[2].myVar",
"structC.myArr1[3][4].myVar",
"structA.myArr1[4]",
"structA.myVar"]

Эти строки описывают переменные / массивы из нескольких структур.Целые числа в массивах описывают размер каждого массива.Учитывая, что строка имеет / несколько массивов (1d или 2d), я хочу создать список строк, которые проходят через каждую комбинацию индекса в массиве для этой строки.Я думал об использовании циклов for, но проблема в том, что я не знаю, сколько массивов в данной строке перед запуском скрипта.Таким образом, я не мог сделать что-то вроде

for i in range (0, idx1):
    for j in range (0, idx2):
         for k in range (0, idx3):
               arr.append(“structA.myArr1[%i][%i].myArr[%i]” %(idx1,idx2,idx3))

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

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

indexArr = re.findall('\[(.*?)\]', myString)
//after looping, indexArr = [['6'],['4','2'],['3','4'],['4']]

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

[
["structA.structB.myArr[0].myVar",
"structA.structB.myArr[1].myVar",
...
"structA.structB.myArr[5].myVar”],

[“structB.myArr1[0].myArr2[0].myVar",
"structB.myArr1[0].myArr2[1].myVar",
"structB.myArr1[1].myArr2[0].myVar",
…
"structB.myArr1[3].myArr2[1].myVar”],

[“structC.myArr1[0][0].myVar",
"structC.myArr1[0][1].myVar",
…
"structC.myArr1[2][3].myVar”],

[“structA.myArr1[0]”,
…
"structA.myArr1[3]”],

[“structA.myVar”] //this will only contain 1 string since there were no arrays
]

Я действительно застрял в этом, любая помощь приветствуется.Большое вам спасибо.

1 Ответ

0 голосов
/ 01 декабря 2018

Ключ должен использовать itertools.product для генерации всех возможных комбинаций набора диапазонов и замены их в качестве индексов массива надлежащим образом построенного строкового шаблона.

import itertools
import re
def expand(code):
    p = re.compile('\[(.*?)\]')
    ranges = [range(int(s)) for s in p.findall(code)]
    template = p.sub("[{}]", code)
    result = [template.format(*s) for s in itertools.product(*ranges)]
    return result

Результат expand("structA.structB.myArr[6].myVar") равен

['structA.structB.myArr[0].myVar',
 'structA.structB.myArr[1].myVar',
 'structA.structB.myArr[2].myVar',
 'structA.structB.myArr[3].myVar',
 'structA.structB.myArr[4].myVar',
 'structA.structB.myArr[5].myVar']

и expand("structB.myArr1[4].myArr2[2].myVar") - это

['structB.myArr1[0].myArr2[0].myVar',
 'structB.myArr1[0].myArr2[1].myVar',
 'structB.myArr1[1].myArr2[0].myVar',
 'structB.myArr1[1].myArr2[1].myVar',
 'structB.myArr1[2].myArr2[0].myVar',
 'structB.myArr1[2].myArr2[1].myVar',
 'structB.myArr1[3].myArr2[0].myVar',
 'structB.myArr1[3].myArr2[1].myVar']

, а угловой корпус expand("structA.myVar") естественным образом работает для производства

['structA.myVar']
...