Почему в Python нет операторов ++
и --
?
Почему в Python нет операторов ++ и -?
Ответ 1
Это не потому, что это не имеет смысла; имеет смысл определить "x ++" как "x + = 1, оценивая предыдущую привязку x".
Если вы хотите узнать первоначальную причину, вам придется либо пройти через старые списки рассылки Python, либо спросить кого-нибудь, кто был там (например, Guido), но это достаточно легко, чтобы оправдать после факта:
Простые приращения и декременты не нужны столько, сколько на других языках. Вы не пишете такие вещи, как for(int i = 0; i < 10; ++i)
в Python очень часто; вместо этого вы делаете такие вещи, как for i in range(0, 10)
.
Поскольку он не нужен почти так же часто, гораздо меньше причин дать ему свой особый синтаксис; когда вам нужно увеличивать, +=
обычно просто отлично.
Это не решение того, имеет ли это смысл, или можно ли это сделать - это так, и это возможно. Это вопрос о том, стоит ли извлекать выгоду из основного синтаксиса языка. Помните, что это четыре оператора: postinc, postdec, preinc, predec, и каждый из них должен иметь свои собственные перегрузки класса; все они должны быть указаны и протестированы; он добавит коды операций к языку (подразумевая больший и, следовательно, более медленный движок VM); каждый класс, поддерживающий логическое приращение, должен будет реализовать их (поверх +=
и -=
).
Все это избыточно с +=
и -=
, поэтому оно станет чистым убытком.
Ответ 2
Этот оригинальный ответ, который я написал, является мифом из фольклора вычислений: развенчан Деннисом Ритчи как "исторически невозможным", как отмечено в письмах редакторам коммуникаций ACM Июль 2012 doi: 10.1145/2209249.2209251
Операторы приращения/уменьшения C были изобретены в то время, когда компилятор C был не очень умным, и авторы хотели иметь возможность указать прямое намерение использовать оператор машинного языка, который сохранил несколько циклов для компилятор, который может выполнять
load memory
load 1
add
store memory
вместо
inc memory
и PDP-11 даже поддерживали команды "автоинкремент" и "отложенные автоинкремент", соответствующие *++p
и *p++
, соответственно. См. Раздел 5.3 руководство, если это ужасно любопытно.
Поскольку компиляторы достаточно умны, чтобы обрабатывать трюки оптимизации на высоком уровне, встроенные в синтаксис C, теперь они просто синтаксические удобства.
У Python нет трюков, чтобы передать намерения ассемблеру, потому что он не использует его.
Ответ 3
Я всегда предполагал, что это связано с этой строкой zen python:
Должен быть один - и желательно только один - очевидный способ сделать это.
x ++ и x + = 1 делают то же самое, поэтому нет причин иметь оба.
Ответ 4
Конечно, мы могли бы сказать, что "Гвидо просто так решил", но я думаю, что вопрос действительно о причинах этого решения. Я думаю, есть несколько причин:
- Он смешивает вместе выражения и выражения, что не является хорошей практикой. См. http://norvig.com/python-iaq.html
- Как правило, люди рекомендуют писать менее читаемый код.
- Дополнительная сложность в реализации языка, которая не нужна в Python, как уже упоминалось
Ответ 5
Поскольку в Python целые числа неизменяемы (int + = фактически возвращает другой объект).
Кроме того, c++/- вам нужно беспокоиться о том, что вы делаете post-increment/decment, и требуется еще одно нажатие клавиши x+=1
. Другими словами, это позволяет избежать возможной путаницы за счет очень небольшого выигрыша.
Ответ 6
Ясность!
Python много о ясности, и ни один программист не может правильно угадать значение --a
, если он/он не изучил язык, имеющий эту конструкцию.
Python также много говорит о предотвращении конструкций, которые допускают ошибки, а операторы ++
, как известно, являются богатыми источниками дефектов.
Эти две причины достаточно, чтобы не иметь этих операторов в Python.
Решение о том, что Python использует отступы, чтобы отметить блоки чем синтаксические средства, такие как форма бревна начала/конца или обязательная концевая маркировка основана в основном на тех же соображениях.
Для иллюстрации рассмотрим обсуждение вокруг введения условного оператора (в C: cond ? resultif : resultelse
) в Python в 2005 году.
Прочитайте хотя бы первое сообщение и сообщение о решении этого обсуждение (ранее было несколько предшественников по той же теме).
Общая информация: Часто упоминаемый в нем PEP - это "Предложение расширения Python" PEP 308. LC означает понимание списка, GE означает выражение генератора (и не волнуйтесь, если это вас смутит, они ни один из немногих сложных пятен Python).
Ответ 7
Это было просто спроектировано именно так. Операторы приращения и декремента - это всего лишь ярлыки для x = x + 1
. Python обычно применяет стратегию проектирования, которая уменьшает количество альтернативных способов выполнения операции. Расширенное назначение является ближайшей вещью для операторов increment/decment в Python, и они даже не добавлялись до Python 2.0.
Ответ 8
Мое понимание того, почему у python нет оператора ++
: Когда вы пишете это в python a=b=c=1
, вы получите три переменные (метки), указывающие на один и тот же объект (значение 1). Вы можете проверить это, используя функцию id, которая вернет адрес памяти объекта:
In [19]: id(a)
Out[19]: 34019256
In [20]: id(b)
Out[20]: 34019256
In [21]: id(c)
Out[21]: 34019256
Все три переменные (метки) указывают на один и тот же объект. Теперь добавьте одну переменную и посмотрите, как она влияет на адреса памяти:
In [22] a = a + 1
In [23]: id(a)
Out[23]: 34019232
In [24]: id(b)
Out[24]: 34019256
In [25]: id(c)
Out[25]: 34019256
Вы можете видеть, что переменная a
теперь указывает на другой объект как переменные b
и c
. Поскольку вы использовали a = a + 1
, это явно ясно. Другими словами, вы назначаете совершенно другой объект для метки a
. Представьте себе, что вы можете написать a++
, это предполагает, что вы не назначили переменному a
новый объект, а добавили увеличение. Все это - ИМХО для минимизации путаницы. Чтобы лучше понять, как работают переменные python:
Является ли Python по значению или по вызову? Ни.
Передает ли Python по значению или по ссылке?
Является ли Python передачей по ссылке или передачей по значению?
Python: Как передать переменную по ссылке?
Понимание переменных Python и управления памятью
Эмуляция поведения пошагового значения в python
Ответ 9
Я очень новичок в python, но я подозреваю, что причина связана с тем, что между изменяемыми и неизменяемыми объектами внутри языка. Теперь я знаю, что x ++ можно легко интерпретировать как x = x + 1, но он СМОТРЕТЬ, как вы увеличиваете на месте объект, который может быть неизменным.
Просто мое предположение/чувство/догадка.
Ответ 10
Во-первых, Python оказывает косвенное влияние только на C; на него сильно влияет ABC, у которого, по- видимому, нет этих операторов, поэтому не должно быть большого удивления не найти их на Python.
Во-вторых, как говорили другие, приращение и декремент поддерживаются +=
и -=
уже.
В-третьих, полная поддержка набора операторов ++
и --
обычно включает в себя поддержку как префиксных, так и постфиксных версий. В C и C++ это может привести к тому, что всевозможные "прекрасные" конструкции, которые кажутся мне, противоречат духу простоты и прямолинейности, которые охватывает Python.
Например, в то время как оператор C while(*t++ = *s++);
может показаться простым и элегантным для опытного программиста, для кого-то, кто его изучает, это ничего, кроме простого. Бросьте смесь префиксов и постфиксных приращений и декрементов, и даже многим профессионалам придется остановиться и немного подумать.
Ответ 11
Я считаю, что это связано с вероучением Python, который "явный лучше, чем неявный".
Ответ 12
Возможно, это связано с тем, что @GlennMaynard рассматривает этот вопрос, как в сравнении с другими языками, но в Python вы делаете что-то вроде python. Это не вопрос "почему". Он есть, и вы можете делать то же самое с x+=
. В Zen of Python дается: "должен быть только один способ решить проблему". Множественные выборы велики в искусстве (свобода выражения), но паршивые в технике.
Ответ 13
Класс операторов ++
- это выражения с побочными эффектами. Это вообще не встречается в Python.
По той же причине назначение не является выражением в Python, тем самым предотвращая общую идиому if (a = f(...)) { /* using a here */ }
.
Наконец, я подозреваю, что оператор не очень согласуется с семантикой ссылок Pythons. Помните, что Python не имеет переменных (или указателей) с семантикой, известной из C/С++.
Ответ 14
Может быть, лучший вопрос заключается в том, чтобы спросить, почему эти операторы существуют в C. K & R вызывает необычные приращения и сокращения операторов (раздел 2.8, стр. 46). Введение называет их "более краткими и часто более эффективными". Я подозреваю, что тот факт, что эти операции всегда возникают при манипулировании указателями, также сыграл определенную роль в их введении. В Python, вероятно, было принято решение, что нет смысла пытаться оптимизировать приращения (на самом деле я просто сделал тест на C, и кажется, что сборка, созданная gcc, использует addl вместо вкл. В обоих случаях), и нет арифметика указателя; так что это был бы просто еще один способ сделать это, и мы знаем, что Python ненавидит это.
Ответ 15
как я понял, поэтому вы не будете думать, что значение в памяти изменилось. в c, когда вы выполняете x ++, значение x в памяти изменяется. но в python все числа неизменны, поэтому адрес, который x указал, все еще имеет x не x + 1. когда вы пишете x ++, вы думаете, что x изменит то, что действительно происходит, так это то, что x refrence изменяется на место в памяти, где x + 1 хранится или воссоздает это местоположение, если doe не существует.
Ответ 16
Завершить уже хорошие ответы на этой странице:
Предположим, что мы решили сделать это, префикс (++i
), который сломал бы унарные + и - операторы.
Сегодня префикс ++
или --
ничего не делает, потому что он дважды активирует оператор унарного плюса (ничего не делает) или унарный минус дважды (дважды: отменяет сам)
>>> i=12
>>> ++i
12
>>> --i
12
Итак, это потенциально может нарушить эту логику.
Ответ 17
Я думаю, что это относится к понятиям изменчивости и неизменности объектов. 2,3,4,5 являются неизменяемыми в питоне. См. Изображение ниже. 2 имеет фиксированный идентификатор до этого процесса python.
x++ по существу означает прирост места на месте, такой как C. В C x++ выполняет приращения на месте. Итак, x = 3, а x++ увеличит 3 в памяти до 4, в отличие от python, где 3 будет существовать в памяти.
Таким образом, в python вам не нужно воссоздавать значение в памяти. Это может привести к оптимизации производительности.
Это навязчивый ответ.
Ответ 18
Я знаю, что это старый поток, но наиболее распространенный вариант использования ++i не рассматривается, это ручная индексация наборов, когда нет предоставленных индексов. Именно поэтому Python предоставляет enumerate()
Пример: в любом конкретном языке, когда вы используете такую конструкцию, как foreach, для итерации по набору - для примера мы даже скажем, что это неупорядоченный набор, и вам нужен уникальный индекс для всего, чтобы отличать их, скажем,
i = 0
stuff = {'a': 'b', 'c': 'd', 'e': 'f'}
uniquestuff = {}
for key, val in stuff.items() :
uniquestuff[key] = '{0}{1}'.format(val, i)
i += 1
В подобных случаях python предоставляет метод перечисления, например
for i, (key, val) in enumerate(stuff.items()) :
Ответ 19
В других ответах описано, почему это не нужно для итераторов, но иногда это полезно при назначении для увеличения переменной в строке, вы можете добиться того же эффекта, используя кортежи и множественное присваивание:
b = ++a
становится:
a,b = (a+1,a+1)
и b = a++
становится:
a,b = a+1, a
В Python 3.8 введен оператор присваивания :=
, что позволяет нам достичь foo(++a)
с помощью
foo(a:=a+1)
foo(a++)
все еще неуловим.
Ответ 20
Оператор++ не совсем такой же оператор + =. На самом деле результат обоих одинаковый, но использование имеет определенную разницу. Например, вы можете использовать оператор ++ в тернарной условной, для цикла и т.д., Но не можете использовать + =. Внизу мы чувствуем потребность ++ и -, по этой причине.
Ответ 21
Вы можете использовать
element = iter(data_list)
a = next(element)
b = next(element)
c = next(element)