Python: Yok'u boş dizeye dönüştürmenin en deyimsel yolu?


156

Aşağıdakileri yapmanın en deyimsel yolu nedir?

def xstr(s):
    if s is None:
        return ''
    else:
        return s

s = xstr(a) + xstr(b)

Güncelleme: Tryptich'in str (s) kullanma önerisini ekliyorum; Vinay Sajip'in lambda önerisinden çok etkilendim, ancak kodumu nispeten basit tutmak istiyorum.

def xstr(s):
    if s is None:
        return ''
    else:
        return str(s)

7
Orijinal sözdizimini beğendim. Bence zaten oldukça açık ve okunması kolay.
GuiSim

1
@GuiSim: Önyargılı olabilirim, ancak cevabım neredeyse normal bir İngilizce cümle gibi okuyor ...
SilentGhost

1
"S Yok ise, boş bir dize döndürün; aksi takdirde [s] dizesini döndürün." Sorudaki kod da normal İngilizce bir cümle gibi okunur.

a) Dize s, anahtarın bulunmadığı birdict.get(key, '')
dikte aramasından geldiyse

b) Bu dize dönüşümünü yalnızca çıktı biçimlendirmesi için istiyorsanız (örneğin, yazdırma için), doğrudan '... {}'. biçimini (dict.get (1)) `
smci

Yanıtlar:


94

İşlevinizin str()yerleşik gibi davranmasını istiyorsanız , ancak bağımsız değişken Yok olduğunda boş bir dize döndürürseniz, bunu yapın:

def xstr(s):
    if s is None:
        return ''
    return str(s)

Ben başka tutuyorum, ama str (s) ucu için teşekkürler böylece birden fazla tür ele alınabilir. Güzel!
Mark Harrison

12
Veya sadecexstr = lambda s: '' if s is None else str(s)
Michael Mior

2
Ben yazmaya bayılıyorum if not s:yerineif s is None
guneysus

6
@guneysus Aynı değiller: not False == Trueama False is None == False.
Lynn

Teşekkürler @ Linn haklısın. Benim hatamı fark ettim. Ama sher zaman str / unicode türünde veya olduğunu biliyorum (veya varsayalım) None. Evet, Falsebir değer ama
klavyemi

143
def xstr(s):
    return '' if s is None else str(s)

3
Bu sözdizimi 2.5'te tanıtıldı; Python'un önceki sürümleri için kullanabilirsiniz return s is not None and s or ''.
Ben Blank

8
Ben daha çok vaka vurgulamak için geri çevirirsiniz: eğer s Hiçbiri değilse "s"
Ber

5
@Ber: Çifte olumsuzluktan kaçınmak için olduğu gibi saklıyorum.
Nikhil Chelliah

8
Bu, nasıl .. and .. or ..başarısız olduğuna ve neden if-else tercih edildiğine iyi bir örnektir . İçinde iki ince böcek var s is not None and s or ''.

1
return '' if not s else str(s)
Iqbal

110

Muhtemelen en kısa olanı str(s or '')

Çünkü Hiçbiri Yanlış ve x yanlışsa "x veya y" y'yi döndürür. Ayrıntılı bir açıklama için bkz. Boolean Operatörleri . Kısa ama çok açık değil.


1
bu harika, teşekkürler! Asla orbu şekilde kullanmayı düşünmedim
user25064

15
s0, False veya herhangi bir falsy değeri varsa bu işe yaramaz
wisbucky

4
Bu op'nun gerekliliğinden bahsedilmiyor, bu yüzden burada ne anlama geldiğini görmüyorum.
dorvak

2
@dorvak OP çıkışı olması gerektiğini gereksinim hakkında oldukça açık olduğunu ''IFF s is None. Diğer tüm girdiler geri dönmelidir s(ya str(s)da gözden geçirilmiş talepte).
StvnW

2
@fortea: bu işe yaramaz. Öyleyse s, Nonesonucu xstr()boş bir dize olmalıdır, ancak döndürülen str(None)dizeyi verir "None"(dize "None"bir falsy değeri olmadığından
dreamlax

97

Değerin her zaman bir dize veya Yok olacağını biliyorsanız:

xstr = lambda s: s or ""

print xstr("a") + xstr("b") # -> 'ab'
print xstr("a") + xstr(None) # -> 'a'
print xstr(None) + xstr("b") # -> 'b'
print xstr(None) + xstr(None) # -> ''

1
açık ara en pitonik. Python'un None, boş bir liste, boş bir dize, 0, vb. Değerlerini false olarak kabul ettiği gerçeğini kullanır. Ayrıca, veya ifadesinin doğru olan ilk öğeyi veya veya (veya grup gruplarına) verilen son öğeyi döndürmesini de kullanır. Ayrıca lambda fonksiyonlarını kullanır. Sana +10 veririm ama açıkçası bana izin vermeyecek.
Matt

11
Bu 0 ve False (ve bool'a geçtiğinde False olarak değerlendirilen herhangi bir şeyi) dönüştürür ())
Arkady

9
Bunun "açık ara en pitonik" olduğunu düşünmüyorum. Diğer dillerde yaygın bir deyimdir ve Python'da kullanmanın yanlış olduğunu düşünmüyorum, ancak böyle hilelerden kaçınmak için kesin olarak tanıtılan koşullu ifadeler.
Roberto Bonvallet

2
Bu da [], {}vb aynı sonucu vermek Nonearzu edilmez. xstr(False), özellikle, "False"yerine olmalıdır "". Lambdas'ı kötüye kullanmak kötü bir örnek teşkil eder, def xstr(s): return s or ""hepsini tek bir satırda tutmak istediğiniz ir'yi kullanın .

5
Cevabımı en başta "değerin her zaman bir dize veya Hiçbiri olacağını biliyorsanız" ile nitelendirdim.
Vinay Sajip

59

return s or '' belirtilen sorun için iyi çalışacaktır!


4
Bunun s Yanlış veya 0 (orijinal dize sorusu değil, güncellenmiş olan değil) için farklı bir sonuç vereceğini belirtmek gerekir.
Oddthinking

@Oththinking s = Falseveya s = 0büyük olasılıkla kullanımında bir uç durum olacak ve şu şekilde yazarak kolayca azaltılabilirreturn str(s or '')
Willem van Ketwich 13:17

@WillemvanKetwich: Bu tamamen aynı soruna sahip: s (False) 'False' döndürmeli, '' değil. s (0) '' değil '0' döndürmelidir. Aynı şekilde __bool__ veya __nonzero__ tanımlayan bir nesne için.
Garip Düşünce

@Odthinking Demek istediğini anlıyorum. Her durumda, yalnızca OP'nin sorusundaki gibi dize nesneleri için kullanılıyorsa, bu bir sorun olmamalıdır.
Willem van Ketwich

@WillemvanKetwich: Yorumumdaki güncellenmiş soruya ve uyarıya bir göz atın - bu ele
alındı

14
def xstr(s):
   return s or ""

4
Bu döner ''için 0, [], {}, Falseve yanlış benzeri değerler, afiş istediğim bu değil.
StvnW

1
sadece s etrafında str ([...]) koymak: def xstr(s): return str(s) or ""
Federico Simonetta

8

Fonksiyonel yol (tek astar)

xstr = lambda s: '' if s is None else s

1
"def xstr (s): return '', s '' Hiçbiri s ise '' da bir astar değildir, python sonuçta boşluklarla o kadar sıkı değildir
SilentGhost

2
Gerçek bir astar yok, sadece bir satırda yazılmış g
Dario

1
hangi anlamda gerçek bir çevrimiçi astar değil? tercümanınızı kontrol edin - sözdizimi hatası değildir. tüm niyetler ve amaçlar için
lambda'dan

2
Bir değişkene lambda atamak yerine def kullanmanız gereken PEP 8 türleri. Lambda'nın tek gerçek avantajı, ifadenin bir parçası olarak (örneğin başka bir işleve geçerek) yazabilmeniz ve bu avantajın kodda bu şekilde kaybolmasıdır. Def'in bir satırda yazılabileceğini fark edene kadar bunu da yapardım ve sonra PEP 8 bana gitmenin yolunu gösterdi. HER ZAMAN piton tanrılarını takip edin.
Guy

8

Bu binayı diğer cevapların bazılarında yapmak için düzgün bir tek katlı:

s = (lambda v: v or '')(a) + (lambda v: v or '')(b)

hatta sadece:

s = (a or '') + (b or '')

Neden bahsediyorsun (lambda v: v or '')?
Tvde1

Neden olmasın? 1 fiyatı için 2 ipucu! 😀
Willem van Ketwich

1
Lütfen Falseboş listenin de '' olarak değiştirileceğini unutmayın.
Nik O'Lai

0vb. için aynı
Walter Tross

6
def xstr(s):
    return {None:''}.get(s, s)

Bence, oldukça pythonic - buna ne dersiniz: "xstr = lambda s: {None: ''}. Get (s, s)" - her şeyi tek bir katmana indirger.
Juergen

14
Gereksiz yere yavaş (ekstra dik inşaat ve arama) ve okunması daha zor. Oldukça unpythonic.
Triptych

Haklısın. Oldukça başarılı ama python bayt kodunda koşullu bir sıçramayı engelliyor.
tobidope

4
Get () işlev çağrısı en az bir ek koşullu atlama anlamına gelir.
Triptych

1
Soruyu bilmeden veya bakmadan bunun ne yapması gerektiğini söyleyemem get.
Dario

5

Max işlevini kullanıyorum:

max(None, '')  #Returns blank
max("Hello",'') #Returns Hello

Bir çekicilik gibi çalışır;) Sadece dizenin fonksiyonun ilk parametresine koyun.


5
Çünkü 'str'> 'NoneType' çalışır ve CPython'a özgüdür. Gönderen manuel : "sayılar hariç farklı türde nesneler tiplerle göre sıralanır." Ayrıca, türler arası karşılaştırmaya artık izin verilmediği için bu Python 3000'de çalışmaz (TypeError: önemsiz türler: str ()> NoneType ()). Bkz. Python dizeyi ve int'i nasıl karşılaştırır?
14'te plok

Teşekkürler iyi, python 3.x uyumlu kod ile ilerlemek iyi bir fikir değil.
radtek

4

Python 2.4 ile uyumlu olmanız gerekiyorsa yukarıdaki değişiklik

xstr = lambda s: s is not None and s or ''

2

Dizeleri biçimlendirmekse, aşağıdakileri yapabilirsiniz:

from string import Formatter

class NoneAsEmptyFormatter(Formatter):
    def get_value(self, key, args, kwargs):
        v = super().get_value(key, args, kwargs)
        return '' if v is None else v

fmt = NoneAsEmptyFormatter()
s = fmt.format('{}{}', a, b)

1
def xstr(s):
    return s if s else ''

s = "%s%s" % (xstr(a), xstr(b))

5
Bu, tüm yanlış benzeri değerler için boş bir dize döndürür; bu, posterin istediği değildir.
Triptych

1

Aşağıda açıklanan senaryolarda her zaman dökümden kaçınabiliriz.

customer = "John"
name = str(customer)
if name is None
   print "Name is blank"
else: 
   print "Customer name : " + name

Yukarıdaki örnekte, değişken müşterinin değerinin Yok olması durumunda, 'ad'a atanırken ayrıca yayınlanır. 'İf' yantümcesindeki karşılaştırma her zaman başarısız olur.

customer = "John" # even though its None still it will work properly.
name = customer
if name is None
   print "Name is blank"
else: 
   print "Customer name : " + str(name)

Yukarıdaki örnek düzgün çalışacaktır. Bu tür senaryolar, URL, JSON veya XML'den değerler getirildiğinde veya hatta değerlerin herhangi bir manipülasyon için daha fazla tür dökümü gerektirdiğinde çok yaygındır.


0

Kısa devre değerlendirmesi kullanın:

s = a or '' + b or ''

+ Dizelerde çok iyi bir işlem olmadığından, biçim dizelerini daha iyi kullanın:

s = "%s%s" % (a or '', b or '')

2
Bu aynı zamanda 'a' yı, yalnızca Hiçbiri değil, tüm yanlış benzeri değerler için boş dizelere dönüştürür. Örneğin, boş gruplar, listeler ve dikteler OP'nin belirtmediği boş dizelere dönüşür.
Triptych

+iki tel için mükemmel bir operatördür. Sorun yaşadığınız düzinelerce katılmak için kullanmaya çalıştığınızda. İki kişilik, muhtemelen diğer seçeneklerden daha hızlı olacak; her iki durumda da, gürültü var.
kquinn

Benim için +1 çünkü bu benim durumumda tam olarak ihtiyacım olan şey: lambda veya tek bir operatörü değiştirmek için fonksiyon ( or) benim için biraz fazla görünüyor ... str veya None gibi diğer falsly değerlere sahip değilim. Açıklamanın dışında +belirli bir senaryoya bağlı olabilir ve kıyaslama gerekebilir operatörü, bu yanıtın yok değil bir -1 hak
Kentsel

-3

Python v3.7 kullanıyorsanız F dizesini kullanın

xstr = F"{s}"

1
Bu yanlış ve dize döndürür 'None'eğer solduğunu None.
Lawrence
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.