Как создать переменные в цикле python
Перейти к содержимому

Как создать переменные в цикле python

  • автор:

Операторы цикла

Цикл for, также называемый циклом с параметром, в языке Питон богат возможностями. В цикле for указывается переменная и множество значений, по которому будет пробегать переменная. Множество значений может быть задано списком, кортежем, строкой или диапазоном.

Вот простейший пример использования цикла, где в качестве множества значений используется кортеж:

i = 1
for color in 'red', 'orange', 'yellow', 'green', 'cyan', 'blue', 'violet':
print(i,'-th color of rainbow is ', color, sep = '')
i += 1

В этом примере переменная color последовательно принимает значения ‘red’, ‘orange’ и т.д. В теле цикла выводится сообщение, которое содержит название цвета, то есть значение переменной color, а также номер итерации цикла число, которое сначала равно 1, а потом увеличивается на один (инструкцией i += 1 с каждым проходом цикла.

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

for i in 1, 2, 3, 'one', 'two', 'three': 
print(i)

При первых трех итерациях цикла переменная i будет принимать значение типа int, при последующих трех — типа str.

Обьявление переменных в цикле python

Реально ли сделать механизм по которому, цикл пробегаться по словарю и объявляет переменную с именем ключа и которой присваивается соответствующее значения из этого же словаря. P.S. нужно для написания модуля который предназначен для реализации мультиязычности в программе, т.е. доступ к соответствующему словарю языка который берется из файла json и выводу из него сообщения по ключу(mess_id).

Отслеживать

задан 9 ноя 2017 в 0:08

67 2 2 серебряных знака 5 5 бронзовых знаков

Python и локальные переменные внутри цикла

Нет ли способа поиметь в Python’е локальные переменные внутри циклов? Такие, которые не будут загромождать область видимости вовне? Иначе, когда код разрастается на экран-другой, понимать, что к чему, становится всё труднее.

Я знаю, что для хорошего кода тела циклов выносят в функции и методы. Однако клепаемый код — это, зачастую, одноразовые скрипты для статистических расчётов. Которые пишутся в духе «посмотрим на графики от предыдущей итерации и добавим/удалим пяток строк». О проектировании часто речь не идёт вообще, потому как я часто не знаю, что буду писать дальше.

Python здесь — это замена MATLABу.

И таки да, нет ли способа сделать так, чтобы переменные внутри циклов были локальными?

Yak ★
25.09.13 17:41:35 MSK
1 2 →

Прямых способов нет. Но есть возможность например в начале тела цикла создавать объект пустого класса, дальше напихивать в него поля, а в конце тела цикла его убивать.

AIv ★★★★★
( 25.09.13 17:57:58 MSK )

нет ли способа сделать так, чтобы переменные внутри циклов были локальными?

Есть. Взять вместо прыщеподелки любой вменяемый язык программирования.

anonymous
( 25.09.13 17:58:54 MSK )

А какая разница, локальные они для цикла или локальные для функции. Это же не Си, в Питоне их можно использовать повторно для следующего цикла.

kvap ★
( 25.09.13 18:02:09 MSK )
Ответ на: комментарий от anonymous 25.09.13 17:58:54 MSK

Это например какой же?

Yak ★
( 25.09.13 18:07:31 MSK ) автор топика
Ответ на: комментарий от AIv 25.09.13 17:57:58 MSK

Прямых способов нет. Но есть возможность например в начале тела цикла создавать объект пустого класса, дальше напихивать в него поля, а в конце тела цикла его убивать.

Можете показать кодом?

Yak ★
( 25.09.13 18:14:58 MSK ) автор топика
Ответ на: комментарий от Yak 25.09.13 18:14:58 MSK

class Dummy: pass . for . : ns = Dummy() ns.a = . b = . ns.a . . del ns 

ЛИСП же! Не связывайтесь с лавсанчегом, он упорот чуть более чем полностью.

AIv ★★★★★
( 25.09.13 18:20:21 MSK )
Ответ на: комментарий от AIv 25.09.13 17:57:58 MSK

И зачем там объект?

anonymous
( 25.09.13 18:26:36 MSK )
Ответ на: комментарий от AIv 25.09.13 18:20:21 MSK

Это не лавсан, да и упорот он не более иных сиплюсплюсников, явовщиков, хаскелистов, эрлангистов и т.д. (список можно продолжать).

dave ★★★★★
( 25.09.13 18:27:05 MSK )
Ответ на: комментарий от AIv 25.09.13 18:20:21 MSK

А разве ‘with’ не делает как раз примерно того же — объект, который убивается при завершении.

alpha ★★★★★
( 25.09.13 18:29:40 MSK )
Ответ на: комментарий от alpha 25.09.13 18:29:40 MSK

цикл не является выражением.

aedeph_ ★★
( 25.09.13 18:35:14 MSK )
Ответ на: комментарий от aedeph_ 25.09.13 18:35:14 MSK

Это я знаю. Я только не знаю, как его правильно делать выражением. Неужели и правда втыкать класс-затычку как у AIv?

Yak ★
( 25.09.13 18:36:19 MSK ) автор топика
Ответ на: комментарий от Yak 25.09.13 18:36:19 MSK

Можно свой оператор assignment’а написать, возвращающий строчку для exec’а, который будет кроме просто «=» дампать переменные в специальные Set’ы, а также свой for, который будет подчищать за собой.

Но разумеется, так делать не нужно.

aedeph_ ★★
( 25.09.13 18:42:04 MSK )

Сам себе придумал проблему, сам её и решай, мы-то тут при чём.

anonymous
( 25.09.13 18:45:31 MSK )

В Perl’ике перед переменной достаточно поставить my , например.

Наверняка в питоне есть что-то подобное.

makyrros
( 25.09.13 18:47:40 MSK )
Ответ на: комментарий от Yak 25.09.13 18:36:19 MSK

Зачем тебе класс-затычка? Сделай «del a, b, c» после цикла и радуйся.

anonymous
( 25.09.13 18:49:30 MSK )
Ответ на: комментарий от anonymous 25.09.13 18:49:30 MSK

Да, но а если их там с десяток?

Yak ★
( 25.09.13 18:52:05 MSK ) автор топика
Ответ на: комментарий от Yak 25.09.13 18:52:05 MSK

Выдели в функции циклы.

zz ★★★★
( 25.09.13 18:57:31 MSK )
Ответ на: комментарий от aedeph_ 25.09.13 18:35:14 MSK

Я сразу скажу что я чайник, и не понимаю.

Если допустим я сделаю так:

with a() as A: for: do_smth(A) 

то для A по окончании будет вызываться __exit__(), который может это A прибивать. И вроде бы это то же самое, что предлагает AIv . Нет?

alpha ★★★★★
( 25.09.13 18:58:17 MSK )
Последнее исправление: alpha 25.09.13 18:58:39 MSK (всего исправлений: 1)

Ответ на: комментарий от zz 25.09.13 18:57:31 MSK

Тогда будет немного тяжелее перекраивать код на ходу.

Yak ★
( 25.09.13 18:58:36 MSK ) автор топика
Ответ на: комментарий от zz 25.09.13 18:57:31 MSK

def mahlopp: for blah mahloop() def mahotherlopp: for blah mahotherlopp() 

Можно прямо в теле метода локальные функции делать.

zz ★★★★
( 25.09.13 18:59:41 MSK )
Ответ на: комментарий от zz 25.09.13 18:59:41 MSK

А вообще можно даже одно имя пользовать.

zz ★★★★
( 25.09.13 19:01:30 MSK )
Ответ на: комментарий от Yak 25.09.13 18:58:36 MSK
zz ★★★★
( 25.09.13 19:01:44 MSK )

Переменные внутри циклов и так локальные. Тебе нужен аналог let из лиспа или что? Такого нет. И в питоне это особо вообще никак не мешает — если тебе нужны такие же имена после цикла: вариант с del’ом уже предложили, второй вариант — берешь и переопределяешь переменные.

alienclaster ★★★
( 25.09.13 19:55:53 MSK )

# coding: utf-8 # быдлокодим def foo(): while 1: old_globals = globals().keys() yield new_globals = globals().keys() for var in new_globals: if var not in old_globals: globals().pop(var) yield foo = iter(foo()) # используем next(foo) for i in xrange(5): j = k = i next(foo) # проверяем print i, j, k # профит! 

Virtuos86 ★★★★★
( 25.09.13 20:33:56 MSK )
Ответ на: комментарий от alienclaster 25.09.13 19:55:53 MSK

Переменные внутри циклов и так локальные.

Тело цикла не является блоком кода, вводящим отдельное локальное пространство имен. Поэтому переменные в цикле определяются в том же неймспейсе, где определен цикл (то бишь переменная цикла). Если циклы находятся на уровне модуля (как у ТС), то есть в глобальном пространстве имен, то и их переменные глобальны. Такое же поведение у list comprehensions было, поправили не помню в какой версии.

Virtuos86 ★★★★★
( 25.09.13 20:43:38 MSK )
Последнее исправление: Virtuos86 25.09.13 20:45:17 MSK (всего исправлений: 1)

Ответ на: комментарий от Virtuos86 25.09.13 20:33:56 MSK

опять же, на немного лохматых версиях питоши вместо

Virtuos86 ★★★★★
( 25.09.13 20:49:44 MSK )
Ответ на: комментарий от Virtuos86 25.09.13 20:33:56 MSK

Неплохо, однако предыдущее состояние переменных он не возвращает, только выкидывает новые.

aedeph_ ★★
( 26.09.13 00:05:46 MSK )

Как вариант делай приставку к переменным local_ Только не забывай их обнулять. Будешь знать что в local_ нету ничего важного и не страшно если переменная с таким именем уже встречалась. Как я понял тебе же главное не обратится к уже существующей переменной или не переопределить уже существующею? тогда прокатит. Помоему самый простой вариант.

local_num, local_f = '', '' 

matrixd
( 26.09.13 02:57:22 MSK )

ТС, тебе не стыдно? Смотри сколько говнокода уже сгенерировано. Если портянка большая, то ответ напрашивается сам собой — разбить. Если это одноразовая большая портянка, то опять всё очевидно — забить. Проблема яйца выеденного не стоит.

anonymous
( 26.09.13 03:02:27 MSK )
Ответ на: комментарий от aedeph_ 26.09.13 00:05:46 MSK

Предыдущее? Хех, тогда только в функции циклы выносить, иначе костыли будут шикарные.

import copy a, b, c = 1, 2, 3 code = '''\ a, b, c = 4, 5, 6 ''' exec code in copy.deepcopy(globals()) print a, b, c 

Код не проверял, не на чем. Но сомнительно, что глубокое копирование будет хорошо работать на реальных пользовательских объектах, как на сферических примерах.

Virtuos86 ★★★★★
( 26.09.13 04:34:40 MSK )
Ответ на: комментарий от Virtuos86 25.09.13 20:43:38 MSK

Тело цикла не является блоком кода, вводящим отдельное локальное пространство имен. Поэтому переменные в цикле определяются в том же неймспейсе, где определен цикл (то бишь переменная цикла).

Да, действительно — это я фигню сказал, хотя сказал там же, что let отсутствует.

Если циклы находятся на уровне модуля (как у ТС), то есть в глобальном пространстве имен, то и их переменные глобальны.

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

Такое же поведение у list comprehensions было, поправили не помню в какой версии

alienclaster ★★★
( 26.09.13 05:03:59 MSK )
Ответ на: комментарий от alienclaster 26.09.13 05:03:59 MSK

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

ТС написал, зачем ему. Хотя настоящий ответ — лень, первейший источник быдлокода :->.

Но-но, без розжига. Не все так однозначно. Те же генераторные выражения такой болезнью изначально не страдали. А l.c. это практически сахар для цикла for с накопителем, потому и копирует его поведение. А оно вот такое. Короче, один из python tips.

Virtuos86 ★★★★★
( 26.09.13 05:32:45 MSK )

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

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

P.S. за тролленг питона разве что зачёт. «Код разрастается» — ну, нашел причину)

anonymous
( 26.09.13 05:38:38 MSK )
Ответ на: комментарий от Virtuos86 26.09.13 04:34:40 MSK

Не не не, никакого deepcopy, это полный Содом. Изменение мутабельных (мутация того же объекта) трогать не надо, его могли, и это даже очень вероятно, изменять сознательно. А вот новый assignment в блоке, который затёр старый, следует откатить. Разумеется для питона этого сделать без переопределения (в голове, хотя бы) «=» не выйдет, поэтому и быдлоязычок, и говноскоупинг.

def x(): a = False def y(): print a a = True return y 

aedeph_ ★★
( 26.09.13 06:31:35 MSK )
Ответ на: комментарий от Virtuos86 26.09.13 05:32:45 MSK

это практически сахар для цикла for с накопителем

А почему не сахар над list(x for x in iterable)?

aedeph_ ★★
( 26.09.13 06:33:41 MSK )
Ответ на: комментарий от aedeph_ 26.09.13 06:33:41 MSK

Потому что list(x for x in iterable) это сахар над list((x for x in iterable)), а генераторные выражения появились намного позднее генераторов списков.

Virtuos86 ★★★★★
( 26.09.13 10:12:00 MSK )
Последнее исправление: Virtuos86 26.09.13 10:12:41 MSK (всего исправлений: 1)

Ответ на: комментарий от aedeph_ 26.09.13 06:31:35 MSK

Теперь понял. Однако, в питоне есть блоки кода — это функции, определяемые инструкциями «def» и «lambda». Если нужна функциональность блоков кода, то надо использовать их, а не пенять, что вещи, не предназначенные для этого, не удается использовать не по назначению. Теперь что касается переопределения «=». Есть два пути. Первый, чернокнижный: можно написать свой кодек, который при парсинге и разборе исходника будет запоминать определяемые переменные и бить по рукам при их повторном переопределении. Все это отслеживается на этапе даже не «компиляции», а чуть пораньше, и динамику не учитывает. Не говоря уже о том, что это уже и не питон будет. Кодек — это то, что указывается в модуле как

В принципе, для себя вполне приемлемый вариант.

Второй: наподобие того, что предложил AIv. Пишем свой класс-неймспейс, переопределяем для него __getattribute__/__setattr__, создаем инстанс этого класса (назовем его «let»), переменные регистрируем как атрибуты let. Дальше контролируем доступ к ним как угодно. Я такое видел, имхо неизящно и избыточно.

Virtuos86 ★★★★★
( 26.09.13 10:48:45 MSK )
Ответ на: комментарий от Virtuos86 26.09.13 10:12:00 MSK

Странно, всегда считал, что genexpr появился за одну минорную версию до lc, но был неправ, 2.0 (2000) vs 2.4 (2002)

Как создать переменные в цикле python

Цикл for , также называемый циклом с параметром, в языке Питон богат возможностями. В цикле for указывается переменная и множество значений, по которому будет пробегать переменная. Множество значений может быть задано списком, кортежем, строкой или диапазоном.

Вот простейший пример использования цикла, где в качестве множества значений используется кортеж:

i = 1 for color in 'red', 'orange', 'yellow', 'green', 'cyan', 'blue', 'violet': print('#', i, ' color of rainbow is ', color, sep = '') i += 1

В этом примере переменная color последовательно принимает значения ‘red’ , ‘orange’ и т.д. В теле цикла выводится сообщение, которое содержит название цвета, то есть значение переменной color , а также номер итерации цикла число, которое сначала равно 1, а потом увеличивается на один (инструкцией i += 1 с каждым проходом цикла.

Инструкция i += 1 эквивалентна конструкции i = i + 1 (это просто сокращенная запись). Такую сокращенную запись можно использовать для всех арифметических операций: *= , -= , /= , %= .

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

for i in 1, 2, 3, 'one', 'two', 'three': print(i)

При первых трех итерациях цикла переменная i будет принимать значение типа int , при последующих трех — типа str .

2. Функция range

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

Для повторения цикла некоторое заданное число раз n можно использовать цикл for вместе с функцией range :

for i in range(4): # равносильно инструкции for i in 0, 1, 2, 3: # здесь можно выполнять циклические действия print(i) print(i ** 2) # цикл закончился, поскольку закончился блок с отступом print('Конец цикла')

В качестве n может использоваться числовая константа, переменная или произвольное арифметическое выражение (например, 2 ** 10 ). Если значение n равно нулю или отрицательное, то тело цикла не выполнится ни разу.

Функция range может также принимать не один, а два параметра. Вызов range(a, b) означает, что индексная переменная будеть принимать значения от a до , то есть первый параметр функции range , вызываемой с двумя параметрами, задает начальное значение индексной переменной, а второй параметр — первое значение, которое индексная переменная принимать не будет. Если же a ≥ b , то цикл не будет выполнен ни разу. Например, для того, чтобы просуммировать значения чисел от 1 до n можно воспользоваться следующей программой:

sum = 0 n = 5 for i in range(1, n + 1): sum += i print(sum)

В этом примере переменная i принимает значения 1, 2, . n , и значение переменной sum последовательно увеличивается на указанные значения.

Наконец, чтобы организовать цикл, в котором индексная переменная будет уменьшаться, необходимо использовать функцию range с тремя параметрами. Первый параметр задает начальное значение индексной переменной, второй параметр — значение, до которого будет изменяться индексная переменная (не включая его!), а третий параметр — величину изменения индексной переменной. Например, сделать цикл по всем нечетным числам от 1 до 99 можно при помощи функции , а сделать цикл по всем числам от 100 до 1 можно при помощи .

Более формально, цикл при d > 0 задает значения индексной переменной i = a , i = a + d , i = a + 2 * d и так для всех значений, для которых i < b . Если же d < 0 , то переменная цикла принимает все значения i >b .

3. Настройка функции print()

По умолчанию функция print() принимает несколько аргументов, выводит их через пробел, после чего ставит перевод строки. Это поведение можно изменить, используя именованные параметры sep (разделитель) и end (окончание).

print(1, 2, 3) print(4, 5, 6) print(1, 2, 3, sep=', ', end='. ') print(4, 5, 6, sep=', ', end='. ') print() print(1, 2, 3, sep='', end=' -- ') print(4, 5, 6, sep=' * ', end='.')

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *