Yanıtlar:
Eşitlik için karşılaştırmıyorsun. Sen atıyorsun .
Python, birden çok hedefe atamanıza izin verir:
foo, bar = 1, 2
atar iki değerleri foo
ve bar
sırasıyla. İhtiyacınız olan tek şey, sağ tarafta bir dizi veya yinelenebilir ve sol tarafta bir isim listesi veya demetidir .
Ne zaman yaparsan:
[] = ""
Eğer bir atanmış boş isimlerin boş listeye dizisini (boş dizeleri hala dizileri vardır).
Esasen yapmakla aynı şeydir:
[foo, bar, baz] = "abc"
nereye ile bitirmek foo = "a"
, bar = "b"
ve baz = "c"
fakat daha az karakter içeren,.
Bununla birlikte, bir dizgeye atama yapamazsınız, bu nedenle ""
bir atamanın sol tarafında hiçbir zaman çalışmaz ve her zaman bir sözdizimi hatasıdır.
Atama beyanları belgelerine bakın :
Bir atama ifadesi, ifade listesini değerlendirir (bunun tek bir ifade veya virgülle ayrılmış bir liste olabileceğini, ikincisinin bir demet oluşturduğunu unutmayın) ve sonuçta ortaya çıkan tek nesneyi soldan sağa hedef listelerin her birine atar.
ve
Bir nesnenin, isteğe bağlı olarak parantez veya köşeli parantez içine alınmış bir hedef listeye atanması, aşağıdaki gibi yinelemeli olarak tanımlanır.
Vurgu benim .
Python'un boş liste için bir sözdizimi hatası vermemesi aslında bir hata! Resmi olarak belgelenmiş dilbilgisi boş bir hedef listeye izin vermez ve boş ()
için bir hata alırsınız. Bkz hata 23275 ; zararsız bir böcek olarak kabul edilir:
Başlangıç noktası, bunun çok uzun süredir var olduğunun ve zararsız olduğunun farkına varmaktır.
Ayrıca bkz. Neden boş bir listeye atama geçerliyken boş bir demete atama geçerli değil?
Dokümantasyondaki Atama ifadeleri bölüm kurallarını takip eder ,
assignment_stmt ::= (target_list "=")+ (expression_list | yield_expression)
Eğer
target list
hedeflerin virgülle ayrılmış listesi: orada hedef listesinde hedefler olduğu ve ilgili hedeflere, soldan sağa öğeler, atanır olarak nesne öğeleri aynı sayıda bir iterable olmalıdır.Nesne, hedef listedeki hedefler ile aynı sayıda öğeye sahip bir dizi olmalıdır ve öğeler soldan sağa karşılık gelen hedeflere atanır.
Öyleyse, dediğinde
[] = ""
""
yinelenebilir (herhangi bir geçerli python dizesi yinelenebilirdir) ve listenin öğeleri üzerinden açılır.
Örneğin,
>>> [a, b, c] = "123"
>>> a, b, c
('1', '2', '3')
Boş bir dizeniz ve boş bir listeniz olduğundan, paketten çıkarılacak hiçbir şey yoktur. Yani hata yok.
Ama bunu dene
>>> [] = "1"
Traceback (most recent call last):
File "<input>", line 1, in <module>
ValueError: too many values to unpack (expected 0)
>>> [a] = ""
Traceback (most recent call last):
File "<input>", line 1, in <module>
ValueError: need more than 0 values to unpack
Bu [] = "1"
durumda, dizeyi açmaya çalışıyorsunuz"1"
boş bir değişkenler listesi üzerinden . Bu nedenle, "paketten çıkarılamayacak kadar çok değerden (0 beklenen)" şikayet ediyor.
Aynı şekilde [a] = ""
boş bir dizeniz olması durumunda, gerçekten paketten çıkarılacak bir şey yoktur, ancak onu tek bir değişken üzerinden açarsınız, ki bu yine mümkün değildir. Bu nedenle, "paketini açmak için 0'dan fazla değere ihtiyaç duyduğundan" şikayet ediyor.
Bunun dışında, fark ettiğiniz gibi,
>>> [] = ()
()
boş bir demet olduğu için de hata atmaz.
>>> ()
()
>>> type(())
<class 'tuple'>
ve boş bir liste üzerine açıldığında, açılacak hiçbir şey yoktur. Yani hata yok.
Ama ne zaman yaparsan
>>> "" = []
File "<input>", line 1
SyntaxError: can't assign to literal
>>> "" = ()
File "<input>", line 1
SyntaxError: can't assign to literal
hata mesajının dediği gibi, bir dize değişmezi atamaya çalışıyorsunuz. Bu mümkün değil. Bu yüzden hataları alıyorsun. Demek gibi
>>> 1 = "one"
File "<input>", line 1
SyntaxError: can't assign to literal
iç organlar
Dahili olarak, bu atama işlemi UNPACK_SEQUENCE
operasyon koduna çevrilecek ,
>>> dis(compile('[] = ""', "string", "exec"))
1 0 LOAD_CONST 0 ('')
3 UNPACK_SEQUENCE 0
6 LOAD_CONST 1 (None)
Burada, dize boş olduğu için zamanları UNPACK_SEQUENCE
kaldırır 0
. Ama böyle bir şeye sahip olduğun zaman
>>> dis(compile('[a, b, c] = "123"', "string", "exec"))
1 0 LOAD_CONST 0 ('123')
3 UNPACK_SEQUENCE 3
6 STORE_NAME 0 (a)
9 STORE_NAME 1 (b)
12 STORE_NAME 2 (c)
15 LOAD_CONST 1 (None)
18 RETURN_VALUE
sıra 123
sağdan sola yığına açılır. Yani, yığının tepesi olur 1
ve bir sonraki olur 2
ve sonuncusu olur 3
. Daha sonra sol taraftaki ifadeden değişkenlere yığının tepesinden tek tek atar.
BTW, Python'da, aynı ifadede birden çok atamayı bu şekilde yapabilirsiniz. Örneğin,
a, b, c, d, e, f = u, v, w, x, y, z
bu işe yarar, çünkü sağ el değerleri bir demet oluşturmak için kullanılır ve daha sonra sol taraftaki değerler üzerinden açılır.
>>> dis(compile('a, b, c, d, e, f = u, v, w, x, y, z', "string", "exec"))
1 0 LOAD_NAME 0 (u)
3 LOAD_NAME 1 (v)
6 LOAD_NAME 2 (w)
9 LOAD_NAME 3 (x)
12 LOAD_NAME 4 (y)
15 LOAD_NAME 5 (z)
18 BUILD_TUPLE 6
21 UNPACK_SEQUENCE 6
24 STORE_NAME 6 (a)
27 STORE_NAME 7 (b)
30 STORE_NAME 8 (c)
33 STORE_NAME 9 (d)
36 STORE_NAME 10 (e)
39 STORE_NAME 11 (f)
42 LOAD_CONST 0 (None)
45 RETURN_VALUE
ancak klasik takas tekniği a, b = b, a
yığının en üstündeki öğelerin dönüşünü kullanır. Yalnızca iki veya üç öğeniz varsa, demeti oluşturmak ve paketi açmak yerine özel ROT_TWO
ve ROT_THREE
talimatlarla işlenirler.
>>> dis(compile('a, b = b, a', "string", "exec"))
1 0 LOAD_NAME 0 (b)
3 LOAD_NAME 1 (a)
6 ROT_TWO
7 STORE_NAME 1 (a)
10 STORE_NAME 0 (b)
13 LOAD_CONST 0 (None)
16 RETURN_VALUE
dis('[] = ""')
uğramadancompile()
.