С Новым годом! Форум программистов, компьютерный форум, киберфорум
Python для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/9: Рейтинг темы: голосов - 9, средняя оценка - 5.00
107 / 107 / 9
Регистрация: 19.12.2010
Сообщений: 417

Изменение последовательности внутри цикла for, мощность Си-шного for в python

04.01.2012, 23:36. Показов 1905. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте.
Пишу калькулятор на python. Имеется список с операторами ['+', '*'], которые я перебираю:
Python
1
2
for cur_op_num in range(len(opers)):
    cur_op = opers[cur_op_num]
Дело в том, что по алгоритму нужно удалить оператор после выполнения и продолжить с этого же индекса, но, насколько я знаю, в python нет мощности цикла for из Си...
На Си это было бы примерно так:
C
1
2
3
4
5
6
7
8
9
for (int cur_op_num=0;cur_op_num<len(opers); cur_op_num++)
{
    if (some_condition) //Если нужно удалить оператор
        {
            //Удаляем и уменьшаем текущий индекс чтобы после итерации он сохранил своё значение
            opers.RemoveAt(cur_op_num);
            cur_op_num--;
        }
}
А как мне сделать такое же на python, если заранее неизвестно, какие индексы будут удаляться?
Вынести range(len(opers)) в отдельную переменную и править эту последовательность? Использовать while и самому контролировать выход...? Как это лучше сделать?
Заранее спасибо.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
04.01.2012, 23:36
Ответы с готовыми решениями:

Почему не срабатывает изменение границы цикла, принятое внутри цикла?
Работает цикл for-Next V_Rod = UBound(Rod, 2) For j = 1 To V_Rod For k = 1 To UBound(BD, 2) ReDim...

Изменение начального положения цикла внутри этого цикла
есть два маппинга в одном 180000 строк в другом 85000 нужно один прогнать по другому на сопоставление по определенному полю, оба столбца...

Изменение переменной внутри цикла
Задача перебрать файлы в папке и заархивировать в отдельные файлы for /f %%i in (d.txt) do ( arj32 m -e -y AFN_%NOM%...

6
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
05.01.2012, 05:36
Лучший ответ Сообщение было отмечено как решение

Решение

А так не подойдет?
Python
1
2
3
4
5
6
7
8
9
10
11
12
>>> sequence = ['one', 'two', 'three', 'four']
>>> for item in sequence[:]:
...     if input('Delete item {} [Y/N]? '.format(item)) in 'yY':
...             sequence.remove(item)
... 
Delete item one [Y/N]? n
Delete item two [Y/N]? y
Delete item three [Y/N]? n
Delete item four [Y/N]? n
>>> sequence
['one', 'three', 'four']
>>>
Приведи минимальный работающий пример на С.
3
107 / 107 / 9
Регистрация: 19.12.2010
Сообщений: 417
05.01.2012, 23:59  [ТС]
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <iostream>
using namespace std;
 
int * DelInd (int * arr, int len, int ind)
{
    // Удаляем индекс путём создания нового массива (указателя на область с кучей int) длиной len - 1
    // И копированием туда всего, кроме ind-ого элемента.
    len--;
    int * new_arr = new int[len];
    for (int i = 0; i < ind; i++)
    {
        new_arr[i] = arr[i];
    }
    for (int i = ind; i < len; i++)
    {
        new_arr[i] = arr[i + 1];
    }
    //Удаляем старый массив.
    delete arr;
    return new_arr;
}
 
int GetMin(int * arr, int len)
{
    int min = arr[0];
    for (int i = 1; i < len; i++)
    {
        if (arr[i] < min)
            min = arr[i];
    }
    return min;
}
 
 
int GetMax(int * arr, int len)
{
    int max = arr[0];
    for (int i = 1; i < len; i++)
    {
        if (arr[i] > max)
            max = arr[i];
    }
    return max;
}
 
void main()
{
    //Массив операторов
    int op_pr_len = 3;
    int * opers = new int [op_pr_len];
    //Массив приортитетов
    //Приоритеты мало связаны с операторами, т.е. у одного '+' может быть приоритет 1, а у другого 0 (приоритеты меняются скобками).
    int *priors = new int [op_pr_len];
    //Массив чисел
    int digs_len = 4;
    int * digs = new int[digs_len];
 
    //Заполняем их
    opers[0] = '*'; //Приоритет по-умолчанию 0
    opers[1] = '+'; //Приоритет по-умолчанию 1
    opers[2] = '-'; //Приоритет по-умолчанию 1
 
    priors[0] = 0; //Приоритет у '*' по-умолчанию 0, значит скобок нет.
    priors[1] = 1; //Приоритет у '-' по-умолчанию 1, значит скобок нет.
    priors[2] = 0; //Приоритет у '+' по-умолчанию 1, а здесь 0, значит есть ОДНА пара скобок (1-0).
 
    digs[0] = 10;
    digs[1] = 5;
    digs[2] = 7;
    digs[3] = 3;
    //Т.е. исходное выражение: 10 * 5 + (7 - 3), ответ должен быть равен 54
 
    int pr_min = GetMin(priors, op_pr_len);
    int pr_max = GetMax(priors, op_pr_len);
 
    //Перебираем операторы
    for (int i_op = 0; i_op < op_pr_len; i_op++)
    {
        //Перебираем все приоритеты
        for (int i_pr = pr_min; i_pr <= pr_max; i_pr++)
        {
            // И вычисляем сначала все операторы с наименьшим приоритетом, постепенно повышая приоритет в i_pr.
            // Если приоритет текущего оператора равен тому приоритету, который мы сейчас обрабатываем, то вычисляем его.
            if (priors[i_op] == i_pr)
            {
                int res = 0;
                //Выполняем нужную операцию над i-ым и (i+1)-ым числом
                switch (opers[i_op])
                {
                    case '+':
                        res = digs[i_op] + digs[i_op+1];
                        break;
                    case '-':
                        res = digs[i_op] - digs[i_op+1];
                        break;
                    case '*':
                        res = digs[i_op] * digs[i_op+1];
                        break;
                }
                //Кладём ответ на место первого числа
                digs[i_op] = res;
                //Удаляем второе число
                int * new_arr = DelInd(digs, digs_len, i_op + 1);
                digs_len--;
                digs = new_arr;
 
                //Удаляем текущий i-ый оператор
                new_arr = DelInd(opers, op_pr_len, i_op);
                opers = new_arr;
 
                //Удаляем текущий i-ый приоритет
                new_arr = DelInd(priors, op_pr_len, i_op);
                priors = new_arr;
 
                op_pr_len--;
 
                //Раз что-то вычисляли - Возвращаем назад
                i_op--;
            }
        }
    }
 
           //Ответ остаётся в digs[0], остальные массивы должны быть пусты.
    cout << "Answer is " << digs[0] << endl;
 
    delete digs;
    delete opers;
 
    system("pause");
}
Извините за плохо-код... Подзабыл C++...
Проверено на MS VC++ 2010.
Видите, если было вычисление, то удаляем текущие оператор и приоритет, а также второе число И ОСТАЁМСЯ с этим же i_op, на этой же итерации.

На Python у меня пока что-то типа этого, но не работает...
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
def CalculateParsed(parsed):
    """"Вычисление выражения в разобранном виде."""
    # Копируем из разобранного выражения необходимые списки.
    # Числа
    digs = parsed[0][:] # Это неглубокое копирование (срез).
    # Для глубокого копирования импортировать copy и выполнить copy.deepcopy(lst)
    # Операторы
    opers = parsed[1][:]
    # Приоритеты
    priors = parsed[2][:]
    ## Указатель на текущее число
    #cur_dig_num = 0
    # Находим максимальный и минимальный приоритеты.
    min_pr = GetMinPr(priors)
    max_pr = GetMaxPr(priors)
    
    #TODO: Может как-то иначе распознавать разноместность оператора?
    #TODO: Как сохранить предыдущий индекс? Использовать while? Менять последовательность?
    for cur_pr in range(min_pr, max_pr + 1):
        for cur_op_num in range(len(opers)):
            if (priors[cur_op_num] == cur_pr):
                cur_op = opers[cur_op_num]
                is_two_op = False
                cur_op_func = one_ops.get(cur_op)
                if (not cur_op_func):
                    cur_op_func = two_ops.get(cur_op)
                    is_two_op = True
                # Достаём функцию-обработчик данного оператора 
                cur_op_func = cur_op_func[0]
                cur_ans = 0
                if (is_two_op):
                    cur_ans = cur_op_func(digs[cur_op_num], digs[cur_op_num + 1])
                else:
                    cur_ans = cur_op_func(digs[cur_op_num])
                digs[cur_op_num] = cur_ans
                del opers[cur_op_num]
                del priors[cur_op_num]
                if (is_two_op):
                    del digs[cur_op_num + 1]
                # Шаг назад...
                #cur_op_num -= 1
    return digs[0]
С помощью while сделал так (работает):
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
def CalculateParsed(parsed):
    """"Вычисление выражения в разобранном виде."""
    # Копируем из разобранного выражения необходимые списки.
    # Числа
    digs = parsed[0][:] # Это неглубокое копирование (срез).
    # Для глубокого копирования импортировать copy и выполнить copy.deepcopy(lst)
    # Операторы
    opers = parsed[1][:]
    # Приоритеты
    priors = parsed[2][:]
    ## Указатель на текущее число
    #cur_dig_num = 0
    # Находим максимальный и минимальный приоритеты.
    min_pr = GetMinPr(priors)
    max_pr = GetMaxPr(priors)
    
    #TODO: Может как-то иначе распознавать разноместность оператора?
    #TODO: Как сохранить предыдущий индекс? Использовать while? Менять последовательность?
    # Перебираем приоритеты от минимального к максимальному.
    for cur_pr in range(min_pr, max_pr + 1):
        cur_op_num = 0
        # Перебираем операторы
        while (cur_op_num < len(opers)):
            # Если это оператор с приоритетом, который мы сейчас обрабатываем, то вычисляем этот оператор
            if (priors[cur_op_num] == cur_pr):
                cur_op = opers[cur_op_num]
                is_two_op = False
                # Ищем этот оператор в списке одноместных операторов.
                cur_op_func = one_ops.get(cur_op)
                # Если не нашли
                if (not cur_op_func):
                    # Ищем в списке двухместных
                    cur_op_func = two_ops.get(cur_op)
                    # Ставим флаг, что это двухместный оператор.
                    is_two_op = True
                # Сейчас в cur_op_func у нас параметры этого оператора: функция обработчик, приоритет, описание, пример. 
                # Достаём функцию-обработчик данного оператора
                cur_op_func = cur_op_func[0]
                cur_ans = 0
                # В зависимости от того, одноместный или двустный это оператор, вызываем функцию с одним или двумя параметрами
                if (is_two_op):
                    cur_ans = cur_op_func(digs[cur_op_num], digs[cur_op_num + 1])
                    # Удаляем второе число, оно больше нам не нужно.
                    del digs[cur_op_num + 1]
                else:
                    cur_ans = cur_op_func(digs[cur_op_num])
                # Ответ кладём в текущую ячейку
                digs[cur_op_num] = cur_ans
                # Оператор и приоритет удаляем.
                del opers[cur_op_num]
                del priors[cur_op_num]
            else:
                # Если расчётов не было - шаг вперёд, к следующему оператору.
                # Если были, то мы уже на следующем операторе за счёт удаления предыдущего оператора и приоритета
                cur_op_num += 1
    return digs[0]
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
06.01.2012, 08:51
Для удаления массивов в С++ используй не delete, а delete[], иначе кака получится.

В твоем же случае, как мне кажется, использовать while будет вполне логично.

Меня немного смущает, что у твоего уже разобранного выражения такое неудобное представление (следовательно, и сам алгоритм вычисления выглядит кривовато). Может, было бы удобней при разборе строки строить дерево или переводить его в постфиксную нотацию?
1
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
06.01.2012, 12:49
Вот хороший пример (вычисление — функция evaluateStack): http://pyparsing.wikispaces.co... /fourFn.py
1
107 / 107 / 9
Регистрация: 19.12.2010
Сообщений: 417
06.01.2012, 22:52  [ТС]
Ну, переделывать, наверно, уж не стану - времени нет. Если препод не заставит... А так... Действительно, немного нерационально, но... Я немного поправил этот алгоритм, он стал чуть лучше.
Цитата Сообщение от Nameless One Посмотреть сообщение
Вот хороший пример (вычисление — функция evaluateStack): http://pyparsing.wikispaces.co... /fourFn.py
Неплохой пример, только рекурсия...
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
07.01.2012, 05:00
FutureCome, рекурсия там совсем необязательна, и все легко переписывается через цикл
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
07.01.2012, 05:00
Помогаю со студенческими работами здесь

Изменение переменной внутри цикла
Почему в цикле i всё равно изменяется только на 5? for i in range(1, 1000, 5): print(i) i = i * 10

Изменение свойств элемента внутри цикла
Вот такой код: procedure TForm1.Button1Click(Sender: TObject); var i: Integer; begin for i:= 10 to 5000 do begin ...

Изменение счетчика по клику внутри цикла
Здравствуйте. В корзине товары выводятся циклом, внутри каждой записи о выбранном товаре есть кнопка увеличения числа товара(если человек...

Поведение функции отрисовки show() внутри цикла. Python/OpenGL. Создание анимации
Добрый день! Имеется объект графического интерфейса ui. Столкнулась с проблемой, что вне зависимости от расположения функции...

Ошибка: Нельзя изменять значение переменной цикла внутри этого цикла
при запуске в строке If i=k Then i:=i+1; выдает ошибку &quot;Нельзя изменять значение переменной цикла внутри этого цикла&quot;. Объясните...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит токи на L и напряжения на C в установ. режимах до и. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru