Почему в 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 и управления памятью

Эмуляция поведения пошагового значения в python

Функции Python вызывают по ссылке

Код Как Pythonista: Идиоматический 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.

ID of constants and variables

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)