Yanıtlar:
Mantıklı olmadığı için değil; "x ++" ifadesini "x + = 1" olarak tanımlamak ve önceki x "bağlamasını değerlendirmek mükemmel bir anlam ifade eder.
Orijinal nedeni bilmek istiyorsanız, eski Python posta listelerinde dolaşmanız veya orada olan birine (örn. Guido) sormanız gerekecek, ancak gerçekten sonra haklı çıkarmak için yeterince kolay:
Diğer dillerde olduğu kadar basit artış ve azalmaya gerek yoktur. for(int i = 0; i < 10; ++i)
Python'daki gibi şeyleri çok sık yazmazsınız; bunun yerine böyle şeyler yaparsınız for i in range(0, 10)
.
Neredeyse sık ihtiyaç duyulmadığından, ona kendi özel sözdizimini vermek için çok daha az neden vardır; Artırmanız gerektiğinde +=
, genellikle iyidir.
Bu mantıklı olup olmadığına ya da yapıp yapamayacağına karar vermez - yapar ve yapabilir. Bu, yararın dilin temel sözdizimine eklemeye değip değmeyeceği sorusudur. Unutmayın, bu dört operatördür - postinc, postdec, preinc, predec ve bunların her birinin kendi sınıf aşırı yüklerine sahip olması gerekir; hepsinin belirtilmesi ve test edilmesi gerekir; dile opcode ekler (daha büyük ve dolayısıyla daha yavaş bir VM motoru anlamına gelir); mantıksal artışı destekleyen her sınıf (üst üste bunları uygulamak gerekir +=
ve -=
).
Tüm bunlar gereksiz +=
ve -=
net bir kayıp olacak.
i
doğrudan döngüye girebilirsiniz - eğer gerçekten ihtiyacınız varsa ve sadece kullanamazsanızarray.append()
i++
ve ++i
...
++
ve --
tanımlanmamış veya belirtilmemiş sonuçlarla kullanılan adil bir miktarda C ++ kodu ile karşılaştım davranışı. Karmaşık, doğru şekilde ayrıştırılması zor kod yazmayı mümkün kılar.
Yazdığım bu orijinal cevap, bilgisayar folklorundan bir efsanedir : Dennis Ritchie tarafından editörlerin mektuplarına not edildiği gibi "tarihsel olarak imkansız" olarak atıldı ACM'nin İletişim atıldı Temmuz 2012 doi: 10.1145 / 2209249.2209251
C arttırma / azaltma operatörleri, C derleyicisinin çok akıllı olmadığı bir zamanda icat edildi ve yazarlar, bir derleyici için bir avuç döngü kaydeden bir makine dili operatörünün kullanılması gerektiği doğrudan niyetini belirtmek istediler. yapabilir
load memory
load 1
add
store memory
onun yerine
inc memory
ve PDP-11 aşağıdakilere karşılık gelen "oto-artış" ve "oto-artış ertelenmiş" talimatları bile destekledi *++p
*p++
, sırasıyla ve 'ye . Çok meraklıysanız kılavuzun 5.3 bölümüne bakın .
Derleyiciler, C sözdiziminde bulunan üst düzey optimizasyon hilelerini ele alacak kadar akıllı olduklarından, şimdi sadece sözdizimsel bir kolaylık.
Python'un, montajcıya niyetleri iletmek için hileleri yoktur çünkü bir tane kullanmaz.
Her zaman python zen bu çizgi ile ilgili olduğunu varsaydı:
Bunu yapmanın tek ve tercihen tek bir yolu olmalı.
x ++ ve x + = 1 tam olarak aynı şeyi yapar, bu yüzden ikisine birden sahip olmak için bir neden yoktur.
one--
sıfır mı?
one--
cümlede birdir, ama hemen sonra sıfırdır. Dolayısıyla bu 'koan', arttırma / azaltma operatörlerinin açık olmadığını da ima ediyor.
Tabii ki, "Guido bu şekilde karar verdi" diyebiliriz, ama bence soru gerçekten bu kararın nedenleri hakkında. Bence birkaç sebep var:
Çünkü Python'da tamsayılar değiştirilemez (int's + = aslında farklı bir nesne döndürür).
Ayrıca, ++ / ile - arttırma / azaltma öncesi ile ilgili endişelenmeniz gerekir ve yazmak için yalnızca bir tuşa daha basın x+=1
. Başka bir deyişle, çok az kazanç pahasına olası karışıklığı önler.
42++
... böyle bir şey (bir hazır sabiti değiştirme) oldu Gelecekteki tüm kullanımlarını: Bazı eski Fortran derleyici mümkün aslında (ya da okudum bu yüzden) o program çalıştırmasındaki bu değişmez değerin gerçekten farklı bir değeri olacaktır. Mutlu hata ayıklama!
int
genel olarak değişmez olduğu anlamına gelmez . Bir int
C basitçe belleğinde yer belirler. Ve oradaki bitler çok değişkendir. Örneğin, bir referans oluşturabilir int
ve bu referansın referansını değiştirebilirsiniz. Bu değişiklik int
o yere yapılan tüm referanslarda (orijinal değişken dahil) görülebilir . Aynı şey bir Python tamsayı nesnesi için de geçerli değildir.
Python açıklık konusunda çok fazladır ve hiçbir programcı --a
bu yapıya sahip bir dil öğrenmedikçe anlamını doğru bir şekilde tahmin edemez.
Python ayrıca hataları davet eden yapılardan kaçınmakla da ilgilidir ve ++
operatörlerin zengin kusur kaynakları olduğu bilinmektedir. Bu iki neden, bu operatörlerin Python'da olmaması için yeterlidir.
Python'un bir tür başlangıç / bitiş basamaklama veya zorunlu son işaretleme gibi sözdizimsel araçlardan ziyade blokları işaretlemek için girintiyi kullandığı kararı büyük ölçüde aynı hususlara dayanır.
Örnek olarak, 2005'te Python'a bir koşullu operatör (C: cond ? resultif : resultelse
cinsinden) getirme konusundaki tartışmaya bir göz atın . En azından ilk mesajı ve karar mesaj bunun tartışma (daha önce aynı konuda birkaç öncüleri vardı).
Diğer bilgiler: Burada sıkça bahsedilen PEP, "Python Genişletme Teklifi" PEP 308'dir . LC, liste anlama anlamına gelir , GE jeneratör ifadesi anlamına gelir (ve eğer bunlar sizi karıştırırsa endişelenmeyin, Python'un birkaç karmaşık noktasından hiçbiri değildir).
Python'un neden ++
operatör olmadığına dair anlayışım şu: Bunu python'a yazdığınızda a=b=c=1
, aynı nesneyi işaret eden üç değişken (etiket) elde edersiniz (bu değer 1'dir). Bir nesne bellek adresi döndürecek id işlevini kullanarak bunu doğrulayabilirsiniz:
In [19]: id(a)
Out[19]: 34019256
In [20]: id(b)
Out[20]: 34019256
In [21]: id(c)
Out[21]: 34019256
Her üç değişken (etiket) de aynı nesneyi gösterir. Şimdi değişkenlerden birini artırın ve bellek adreslerini nasıl etkilediğini görün:
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
Bu değişkenin a
artık başka bir nesneyi değişken b
ve olarak gösterdiğini görebilirsiniz c
. Çünkü kullandığınız a = a + 1
açıkça belli. Başka bir deyişle, etikete tamamen başka bir nesne atarsınız a
. Yazabileceğinizi düşünün ki a++
, değişken a
yeni nesneye atamadığınızı, ancak daha eski olanı artırdığınızı düşündürür. Bütün bunlar karışıklığı en aza indirmek için IMHO'dur. Daha iyi anlamak için python değişkenlerinin nasıl çalıştığını görün:
Python değere göre çağrı mı, yoksa referans numarası mı? Ne.
Python değere veya referansa göre geçiyor mu?
Python referansla mı yoksa değerle mi?
Python: Bir değişkeni referans olarak nasıl iletirim?
Python değişkenlerini ve Bellek Yönetimini Anlama
Python'da değere göre by-pass davranışını taklit etme
Sadece bu şekilde tasarlandı. Artış ve eksiltme operatörleri sadece kısayollardır x = x + 1
. Python, tipik olarak, bir işlemi gerçekleştirmenin alternatif yollarının sayısını azaltan bir tasarım stratejisi benimsemiştir. Artırılmış atama , Python'daki operatörleri artırmaya / azaltmaya en yakın şeydir ve Python 2.0'a kadar eklenmediler.
return a[i++]
ile return a[i=i+1]
.
Python için çok yeniyim ama bunun nedeni, dilin değişebilir ve değişmez nesneleri arasındaki vurgudan kaynaklandığından şüpheleniyorum. Şimdi, x ++ 'ın x = x + 1 olarak kolayca yorumlanabileceğini biliyorum, ama değişmez olabilecek bir nesneyi yerinde artırıyormuşsunuz gibi görünüyor .
Sadece tahminim / duygu / önsezim.
x++
daha yakın olduğu x += 1
için daha x = x + 1
bu iki değişken nesneler üzerinde de bir fark yaratmak.
İlk olarak, Python sadece dolaylı olarak C'den etkilenir; o ağır etkilenir ABC , görünüşe göre bu operatörler yok o Python Ya onları bulmak için değil, herhangi büyük bir sürpriz olmamalı bu yüzden.
İkincisi, diğerlerinin söylediği gibi, artış ve azalış zaten +=
ve -=
zaten tarafından desteklenmektedir .
Üçüncü olarak, bir ++
ve --
operatör kümesi için tam destek genellikle bunların önek ve son düzeltme sürümlerinin desteklenmesini içerir. C ve C ++ 'da bu, (bana göre) Python'un kucakladığı basitlik ve dürüstlük ruhuna aykırı görünen her türlü "güzel" yapıya yol açabilir.
Örneğin, C ifadesi while(*t++ = *s++);
deneyimli bir programcı için basit ve zarif görünse de, onu öğrenen biri için bu basit bir şeydir. Önek ve düzeltme sonrası artışların ve düşüşlerin bir karışımını atın ve birçok profesyonel bile biraz durup düşünmek zorunda kalacak.
Ben inanıyorum Python inanç "açık dolaylı daha iyidir" kaynaklanıyor.
Bunun nedeni @GlennMaynard'ın konuya diğer dillerle karşılaştırıldığında bakması olabilir , ancak Python'da işleri python yolu ile yaparsınız. Bu 'neden' sorusu değil. Orada ve aynı etkiye sahip şeyleri yapabilirsiniz x+=
. In Python Zen , verilir: "Yalnızca bir sorunu çözmek için bir yol bulunmalıdır." Birden fazla seçenek sanatta mükemmeldir (ifade özgürlüğü) ancak mühendislikte berbattır.
++
Operatörlerin sınıf yan etkileri ile ifadelerdir. Bu genellikle Python'da bulunmayan bir şeydir.
Aynı nedenden ötürü bir ödev Python'da bir ifade değildir, böylece ortak if (a = f(...)) { /* using a here */ }
deyimi önler .
Son olarak, operatörün Pythons referans semantiği ile çok tutarlı olmadığından şüpheleniyorum. Unutmayın, Python'un C / C ++ 'dan bilinen anlambilimiyle değişkenleri (veya işaretçileri) yoktur.
f(a)
burada a
bir liste, değişmez bir nesne.
Belki de daha iyi bir soru, bu operatörlerin neden C'de bulunduğunu sormak olabilir. K&R, arttırma ve azaltma operatörlerini 'olağandışı' olarak adlandırır (Bölüm 2.8 sayfa 46). Giriş onlara 'daha özlü ve genellikle daha verimli' diyor. Bu operasyonların her zaman işaretçi manipülasyonunda ortaya çıkmasının da tanıtımlarında bir rol oynadığından şüpheleniyorum. Python'da muhtemelen artışları optimize etmeye çalışmanın mantıklı olmadığına karar verildi (aslında sadece C'de bir test yaptım ve gcc tarafından oluşturulan montajın her iki durumda da incl yerine addl kullandığı görülüyor) ve yok işaretçi aritmetiği; yani bunu yapmanın sadece bir yolu daha olurdu ve Python'un bunu sevdiğini biliyoruz.
anladığım kadarıyla bellekteki değerin değiştiğini düşünmeyeceksiniz. c ++ ile yaptığınız zaman bellekte x değeri değişir. ancak python'da tüm sayılar değişmez olduğundan x'in işaret ettiği adres x + 1 değil. x ++ yazdığınızda, x değişiminin gerçekte ne olduğunu, x referansının x + 1'in depolandığı bir konum olarak değiştirildiğini veya doe yoksa bu konumu yeniden oluşturduğunu düşünürsünüz.
++
farklı kılan += 1
nedir?
Bu sayfada zaten iyi yanıtları tamamlamak için:
Diyelim ki bunu yapmaya karar veriyoruz ++i
, tekli + ve - operatörlerini kıracak önek ( ).
Bugün, önekleme ++
veya --
hiçbir şey yapmaz, çünkü tekli artı operatöre iki kez (hiçbir şey yapmaz) veya tekli eksi iki kez (iki kez: kendini iptal eder)
>>> i=12
>>> ++i
12
>>> --i
12
Böylece bu potansiyel olarak bu mantığı kırabilir.
Diğer cevaplar, yineleyiciler için neden gerekli olmadığını açıkladı, ancak bazen bir değişkeni satır içi artırmak için atarken faydalıdır, tuples ve çoklu atama kullanarak aynı efekti elde edebilirsiniz:
b = ++a
dönüşür:
a,b = (a+1,)*2
ve b = a++
olur:
a,b = a+1, a
Python 3.8 atama tanıtır :=
bize ulaşmak için izin operatörü foo(++a)
ile
foo(a:=a+1)
foo(a++)
yine de zor.
Bunun nesnelerin değişebilirliği ve değişmezliği kavramlarıyla ilgili olduğunu düşünüyorum. 2,3,4,5 python ile değişmez. Aşağıdaki resme bakın. 2, bu python işlemine kadar kimliği sabitledi.
x ++ esasen C gibi bir yerinde artış anlamına gelir. C'de x ++ yerinde artışlar gerçekleştirir. Bu nedenle, x = 3 ve x ++, bellekte 3'ün var olacağı python'un aksine, bellekte 3'ü 4'e yükseltir.
Böylece python'da, hafızadaki bir değeri yeniden oluşturmanız gerekmez. Bu performans optimizasyonlarına yol açabilir.
Bu önsezi tabanlı bir cevap.
Bu eski bir iş parçacığı olduğunu biliyorum, ancak ++ i için en yaygın kullanım durumu, sağlanan dizinler olmadığında el ile dizin oluşturma olan bu kapsam dahil değildir. Bu durum python'un enumerate ()
Örnek: Herhangi bir dilde, bir kümeyi yinelemek için foreach gibi bir yapı kullandığınızda - örnek uğruna bunun sırasız bir küme olduğunu bile söyleyebiliriz ve her şeyin onları ayırt etmesi için benzersiz bir dizine ihtiyacınız vardır, diyelim
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
Bu gibi durumlarda, python numaralandırma yöntemi sağlar, örn.
for i, (key, val) in enumerate(stuff.items()) :