Python Dynami c для l oop Размер диапазона - PullRequest
1 голос
/ 11 марта 2020

Я пытаюсь добавить Link аргумент в INI-файл, используя python. Пример файла ini:

[sometag]
sometext
sometext
sometext

[sometag2]
sometext2
sometext2
sometext2

[sometag3]
sometext3
sometext3
sometext3

Мне нужно сделать так:

[sometag]
sometext
sometext
sometext

Link = [sometag]

[sometag2]
sometext2
sometext2
sometext2

Link = [sometag2]
...

Мой для l oop:

for i in range(len(m)):
    if m[i] in t:
        for j in xrange(i, len(m)):
            if len(m[j].strip()) == 0 and m[j+1].startswith('['):
                m.insert(j, Link.....
                break


# m = ini_file.readlines()
# t = ['[sometag]', '[sometag2]']

Мой код работает, но это не добавляет ссылку на последние теги. Я нашел почему. Если я добавлю in range(len(m)+100):, тогда код добавит все ссылки.

Похоже, len(m) - это старое значение (stati c?), Потому что я увеличиваю len со вставкой во время l oop. Есть идеи?

Я пробовал что-то вроде insertings = 0, затем range(len(m)+insertings) и после вставки insertings = insertings+1 Но не повезло: (

Ответы [ 2 ]

1 голос
/ 11 марта 2020

Использование range блокирует вас на указанное c количество итераций; range(len(m)) создает range, используя значение len(m) , теперь , и оно никогда не изменяется (это не может быть range s неизменяемыми). Вы хотите такое поведение, точно так же, как вы хотите:

s = '123'
i = int(s)
s = 'abc'

оставить i со значением 123, а не умирать, когда аргумент int задним числом становится 'abc' (позволяя поведению range(len(m)) задним числом измениться, поскольку m изменения будут морально эквивалентными и одинаково безумными).

Изменение list при его повторении вызывает неодобрение, особенно если вы insert делаете до конца list или удаляете элементы. Это просто слишком подвержено ошибкам; в этом случае, когда j принимает начальное значение i и происходит insert, вы вставили значение, которое циклы никогда не увидят (потому что оно будет смотреть на i + 1 далее) при вставке он в j > i будет виден внешним l oop, но не внутренним (и в обоих случаях значение m[j] будет обработано дважды в последовательных циклах).

Как правило, более безопасным решением является создание нового list с нуля, добавление элементов из существующего list по мере необходимости и добавление новых элементов в конец, как вы go. Это также намного быстрее insert по центру list равно O(n) для каждый insert (общая стоимость O(m * n), где m - количество необходимых вставок, n размер ввода), а append амортизируется O(1) (общая стоимость O(m + n)).

1 голос
/ 11 марта 2020

Создать новый список:

new = []
tag = None
for line in m:
    if line.startswith('['):
        if tag:
            new.append('Link = ' + tag)
        tag = line
    new.append(line)
...