Birleştirme için% s neden + 'dan daha iyi?


88

Python %syerine bir dizgiyi birleştirmek için kullanmamız gerektiğini anlıyorum +.

Herhangi birini yapabilirim:

hello = "hello"
world = "world"

print hello + " " + world
print "%s %s" % (hello, world)
print "{} {}".format(hello, world)
print ' '.join([hello, world])

Ama neden ben dışında başka bir şey kullanmalıyım +? Birleştirmeyi basit bir şekilde yazmak daha hızlıdır +. Biçimlendirme dize bakarsanız Sonra türleri örneğin belirtmek %sve %dve bu tür. Türü hakkında açık olmanın daha iyi olabileceğini biliyorum.

Fakat daha sonra +, yazmak daha kolay olsa da birleştirme için kullanımdan kaçınılması gerektiğini okudum . Dizelerin diğer yollardan biriyle birleştirilmesi gerektiğinin açık bir nedeni var mı?


29
Kim daha iyi olduğunu söyledi?
yannis

3
%sbirleştirme için değil, C'lerden türetilmiş dize formatları için bir dönüşüm özelliğidir printf(3). Bunu veya bir birleştirme işlecini kullanmak için durumlar vardır; Kullandığınız durum dogma değil, yargıya dayanmalıdır. Kodu yazmanın ne kadar kolay olduğu tamamen alakasızdır çünkü bunu sadece bir kez yapacaksınız.
Blrfl

Bu soruyu sadece python için değiştirdim (yine de bir python insanı değilim ve hala kodda aksaklıklar olabilir). Lütfen sorduğunuz sorunun bu olduğundan emin olun, uygun güncellemeleri yapın ve C veya Java ile ilgileniyorsanız farklı bir soru sormayı düşünün .

12
Ve şimdi üstün f-dizgileri var ! print(f"{hello} {world}"), değişkenler dizgede oluştukları yerlerde görüldüğü için birleştirme okunabilirliğine sahiptir ve ondan daha hızlıdır str.format.
Enrico Borba

Yanıtlar:


88
  1. Okunabilirlik. Biçim dizgesi sözdizimi, stili verilerden ayırdığı için daha okunur. Ayrıca, Python'da, %ssözdizimi otomatik olarak herhangi bir strtürü içermez str; birleştirme yalnızca ile çalışır strve birleştirme strgerçekleştiremezsiniz int.

  2. Verim. Python'da strdeğişmez, bu nedenle her bir birleştirme çifti için sol ve sağ dize yeni dizgiye kopyalanmalıdır. 10'luk dört dizgiyi birleştirirseniz, sadece 40 yerine (10 + 10) + ((10 + 10) +10) + ((((10 + 10) +10) +10) = 90 karakter kopyalayacaksınız. karakter. Ve ipin sayısı ve ebadı arttıkça işler daha da kötüleşiyor. Java bu durumu bir araya StringBuildergetirme dizisini kullanmak için bir araya getirerek optimize eder , ancak CPython kullanmaz .

  3. Bazı kullanım durumlarında, günlük kitaplığı, günlük giriş dizesini lazily ( logging.info("blah: %s", 4)) oluşturmak için biçim dizesini kullanan bir API sağlar . Günlük kitaplığı, geçerli günlük girişinin bir günlük filtresi tarafından atılacağına karar verirse, performansın iyileştirilmesi için mükemmeldir, bu nedenle dizeyi biçimlendirmesi gerekmez.


31
# 1 için herhangi bir bilimsel ya da ampirik kaynağınız var mı? Çünkü daha az okunabilir olduğunu düşünüyorum (özellikle 2 veya üçten fazla argümanla)
Lovis

4
@ L.Möller: Nihayetinde öznel bir deneyimden (okuma kolaylığı) ne tür bir kaynak beklediğinizden tam olarak emin değilim ama akıl yürütmemi istiyorsanız: 1)% s yer tutucu başına 2 ekstra karaktere ihtiyaç duyuyor vs en az 4 (veya PEP8'i izlerseniz 8, zorlarsanız 13), 2)% s tek bir dizge içine alınır, bu nedenle görsel olarak ayrıştırmak kolaydır; , operator, open string, 3) sözdizimi renklendirme% s her işlev için bir renge sahiptir: string ve yer tutucu, + ile üç renklendirme alırsınız: string, operator ve değişken renklendirme.
Lie Ryan,

4
@ L.Möller: 4) Daha uzun format dizelerini bir değişken veya sözlükte daha uzun format dizeleri koyma seçeneğine sahibim, 5) format dizesi bir config dosyasından, komut argümanlarından veya veri tabanından belirtilen kullanıcı tarafından belirlenebilir , aynı şey birleştirme ile söylenemez. Ama evet, enterpolasyon yapmak için 4-5'ten fazla şeyim olduğunda da% s'yi kullanmam, bunun yerine Python'da% (varname) varyantını veya "{foo}". Format () yöntemini kullanırdım. Açık adların, çok sayıda enterpolasyonlu değişkeni olan daha uzun format dizeleri için okunabilirliği artırdığını düşünüyorum.
Lie Ryan,

2
Neyin "doğru" olduğunu bilmiyorum, bu yüzden kanıtın olup olmadığını soruyorum :-). İkinci yorumunuza gerçekten katılıyorum
Lovis

6
Şüpheli olarak 2 numarayı buldum - belgelendiğin kanıtı var mı? Java'yı çok iyi aşina değilim, ama C # birleştirmede string enterpolasyonundan daha hızlı . # 1 ile tamamen aynı fikirdeyim ve hangisinin ne zaman kullanılacağına karar vermek için gerçekten buna güveniyorum, ancak enterpolasyonun, birleştirme işleminin hiçbirini gerektirmediği bir miktar string ayrıştırma ve karmaşıklık gerektirdiğini unutmamalısınız.
Jimmy Hoffa

48

Soldan sağa okuyan tek kişi ben miyim?

Bana göre kullanmak %s, fiillerin ne olduğunu duymak için çok uzun bir cümlenin sonuna kadar beklemek zorunda olduğum Alman konuşmacıları dinlemek gibi.

Bunlardan hangisi hızlı bir şekilde daha açık?

"your %s is in the %s" % (object, location)

veya

"your " + object + " is in the " + location  

17
Açıkçası bu öznel, çünkü ilkini daha okunaklı buluyorum - ve yazması ve düzenlemesi daha kolay. İkincisi, metni her ikisini de gizleyen ve gürültü ekleyen kodla birleştirir. Mesela boşlukları ikinci sırada yanlış yapmak kolaydır.
JacquesB

5
@JacquesB Aslında beyninizin bu forma o kadar aşina olduğunu düşünüyorum ki hemen parantez içine atlarsınız ve kelimeleri anında değiştirirsiniz. Teknik olarak soldan sağa okuma değil, ama bu tamamen iyi. Ben de bunu yapıyorum, öyleyse evet, 1'in okunması daha kolay, çünkü ikinci alıntılardan önce ve sonra aptal boşluklarla uğraşmak zorunda olduğumu biliyorum ve bununla çalışmak gerçekten yavaş.
Nelson

3
nYıllar sonra aklım da böyle işler ;-) Ama yine de cevabımı bekliyorum. Ve bu, sahip olduğunuz parametreler daha belirgin hale gelir. Sonunda, tek kişilik bir şovsa, aşina olduğunuz ve rahat olduğunuz şeyle devam edin; bir ekip çalışmasıysa tutarlılığı sağlayın ve kod incelemelerini yapın; insanlar ikisine de alışabilirler.
Mawg

4
İlki benim için çok daha okunaklı çünkü cümlenin ortasında daha az "hile" var. Gözümün sonuna kadar bakması daha kolay, o zaman beynimin fazladan alıntıları, boşlukları ve artıları ayrıştırması. Tabii ki, ben şimdi çok Python 3.6 biçim dizeleri tercih: f"your {object} is in the {location}".
Dustin Wyatt

8
Ayrıca değişkenin kendisiyle çevrelenmesi gerektiğinde okumak ve yazmak daha da zor. "your '" + object + "' is in the '" + location + "'"... şu anda bunu doğru yapıp yapmadığımdan bile emin değilim ...
Dustin Wyatt

12

Okunabilirlik argümanını açıklayan bir örnek:

print 'id: ' + id + '; function: ' + function + '; method: ' + method + '; class: ' + class + ' -- total == ' + total

print 'id: %s; function: %s; method: %s; class: %s --total == %s' % \
   (id, function, method, class, total)

(İkinci örneğin yalnızca daha okunaklı değil, aynı zamanda düzenlemek daha kolay olduğunu unutmayın; bir satırdaki şablonu ve bir başındaki değişkenlerin listesini değiştirebilirsiniz)

Ayrı bir konu,% s kodunun da dizgeye dönüştürülmesidir, aksi halde% s kodundan daha az okunabilen str () çağrısı kullanmanız gerekir.


1
İlk açıklamanıza katılmıyorum, ama farklılaşmayı kabul edebiliriz, sadece ikinci satırınız boyunca bir cevap göndermek üzereydim, yani çok oy
Mawg

6

Kullanılması +gereken değil genel olarak kaçınılmalıdır. Çoğu durumda doğru yaklaşım budur. Kullanmak %sveya .join()yalnızca belirli durumlarda tercih edilir ve bunlar daha iyi bir çözüm olduğu zaman oldukça açıktır.

Örneğinizde üç dizgiyi bir araya getiriyorsunuz ve bu örnekte kullanılan örnek +en basit ve en okunaklı olanı ve bu nedenle tavsiye ediliyor .

%sveya daha büyük bir dizenin ortasındaki.format() dizeleri veya değerleri enterpolasyon yapmak istiyorsanız kullanışlıdır . Örnek:

print "Hello %s, welcome to the computer!" % name

Bu durumda %s, ilk dizgiyi birden fazla parçaya bölmekten kaçındığınız için kullanımı daha okunaklıdır. Özellikle birden fazla değeri enterpolasyon yapıyorsanız.

.join() Değişken boyutta bir dizge diziniz varsa ve / veya aynı ayırıcı ile birden fazla dizgiyi birleştirmek istiyorsanız uygundur.


2

Kelime sırası farklı dillerde değişebileceğinden %s, yazılımınızdaki dizelerin çevirisini doğru bir şekilde desteklemek istiyorsanız , formu doldurmak zorunludur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.