Python uzun bir dizeyi kısaltıyor


246

Bir dize Python'da 75 karaktere nasıl kesilir?

JavaScript'te şu şekilde yapılır:

var data="saddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddsaddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddsadddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
var info = (data.length > 75) ? data.substring[0,75] + '..' : data;

Yanıtlar:


427
info = (data[:75] + '..') if len(data) > 75 else data

58
Ben belki de len(data) > 77çift ​​nokta (sadece bir nokta yerine sadece son karakteri bir kısaltmak için anlamsız) için koşul değiştirmek istiyorum .
hasen

5
@hasenj: Bu orijinal koda uymuyor, ama ilk etapta işaret etmem iyi bir öneri.
Marcelo Cantos

2
Dahil olan parenslerin elbette isteğe bağlı olduğunu unutmayın.
Taylor Edmiston

10
@TaylorEdmiston Doğru, ancak günlük kullandıkları 5-10 dilde tüm öncelik kurallarını hatırlamayanlar için oldukça yararlıdır.
Marcelo Cantos

2
Anthony a slice
Marcelo Cantos

126

Daha da kısa:

info = data[:75] + (data[75:] and '..')

2
Bunu yapmak için komik bir yaklaşım. Yine de kompozit bir astar. ^^
Neşeli

3
'..' ifadesini eklerseniz bu çözümün 77 karakteri yok mu?
Mark Chackerian

bu iki dilim işlemi gerçekleştirmiyor mu? Performansın çok önemli olduğu zaman stackoverflow.com/a/52279347/1834057 ile karşılaştırıldığında nasıl performans gösterdiğini merak ediyorum
Nicholas Hamilton

1
Tabii, güzel orijinal cevap, ama Marcelo'nun cevabı daha açık ve dolayısıyla okunabilir (ve dolayısıyla Pythonic) olduğu için daha iyi.
sitnarf

114

Daha da özlü:

data = data[:75]

75 karakterden azsa değişiklik olmaz.


9
Dize kesilirse muhtemelen bir üç nokta eklenmesini istiyor.
FogleBird

4
Haklısın - bunu hiç fark etmedim. Bunu yapmanın diğer cevaplardan daha iyi bir yol olduğunu düşünemiyorum.
neil

82

Python 3.4+ kullanıyorsanız textwrap.shorten, standart kitaplıktan kullanabilirsiniz:

Belirtilen genişliğe sığması için verilen metni daraltın ve kesin.

Önce metindeki boşluk daraltılır (tüm boşluk yerine tek boşluk bırakılır). Sonuç genişliğe sığarsa döndürülür. Aksi takdirde, kalan kelimeler artı yer tutucunun genişliğe sığması için sonuna kadar yeterli kelime bırakılır:

>>> textwrap.shorten("Hello  world!", width=12)
'Hello world!'
>>> textwrap.shorten("Hello  world!", width=11)
'Hello [...]'
>>> textwrap.shorten("Hello world", width=10, placeholder="...")
'Hello...'

8
Pantolonunu gerçekten uzun iplerde (boşluk yok) saçmış gibi görünüyor ve sadece üç nokta çıkarıyor.
elBradford

5
@elBradford (ve diğerleri ile ilgilenen): Bunun nedeni , tek karakterleri değil, sözcüklerishorten() kısaltır . Arama yaptım, ancak kelimeleri değil, tek karakterleri kırpmak için bir yol ya da bir örnek görünmüyor . shorten()TextWrapper
Acsor

Ve satır sonlarını kaldırmanın can sıkıcı yan etkisi var
havlock

Bu OP'nin sorusunu çözmez. Kelime ile kısalır ve hatta boşlukları kaldırır.
Florian Wendelborn



9

Normal ifade ile:

re.sub(r'^(.{75}).*$', '\g<1>...', data)

Uzun teller kesilir:

>>> data="11111111112222222222333333333344444444445555555555666666666677777777778888888888"
>>> re.sub(r'^(.{75}).*$', '\g<1>...', data)
'111111111122222222223333333333444444444455555555556666666666777777777788888...'

Kısa dizeler asla kesilmez:

>>> data="11111111112222222222333333"
>>> re.sub(r'^(.{75}).*$', '\g<1>...', data)
'11111111112222222222333333'

Bu şekilde, bazı durumlarda daha güzel olan dizenin orta kısmını da "kesebilirsiniz":

re.sub(r'^(.{5}).*(.{5})$', '\g<1>...\g<2>', data)

>>> data="11111111112222222222333333333344444444445555555555666666666677777777778888888888"
>>> re.sub(r'^(.{5}).*(.{5})$', '\g<1>...\g<2>', data)
'11111...88888'

dizenizde boşluklar olduğunda işe yaramadı
holms

Neden bu kadar basit bir durum için regex'i kullanasınız?
Bora M. Alper

5

Bu yöntem aşağıdaki durumlarda hiçbirini kullanmaz:

data[:75] + bool(data[75:]) * '..'


4
Sadece mümkün olduğunu göstermek için yazdım. Python'un okunabilirlik felsefesine aykırıdır. Diğer "if" tabanlı yöntemlerle karşılaştırıldığında hiçbir performans avantajı yoktur. Asla kullanmıyorum ve ben de kullanmanızı önermiyorum.
Sassan

4
limit = 75
info = data[:limit] + '..' * (len(data) > limit)

1
Bu en zarif çözüm. Ek olarak, 75tutarsızlıkları önlemek için karakter sınırını (bu örnekte ) bir değişkene çıkarabilirim . limit = 75; info = data[:limit] + '..' * (len(data) > limit)
ekauffmann

3

Yine başka bir çözüm. İle Trueve Falsesonunda test hakkında küçük bir geri bildirim alırsınız.

data = {True: data[:75] + '..', False: data}[len(data) > 75]

2

Bu sadece:

n = 8
s = '123'
print  s[:n-3] + (s[n-3:], '...')[len(s) > n]
s = '12345678'
print  s[:n-3] + (s[n-3:], '...')[len(s) > n]
s = '123456789'     
print  s[:n-3] + (s[n-3:], '...')[len(s) > n]
s = '123456789012345'
print  s[:n-3] + (s[n-3:], '...')[len(s) > n]

123
12345678
12345...
12345...

Önceki tüm cevaplar OP'nin gerçekten ne istediğini düşünmeyi ihmal ediyor - 75 karakterden uzun olmayan bir çıktı dizesi. "Söylediklerimi yapma, istediğimi yapma" programlama ilkesini anlamak için şeref. Tamlık için n <3'ün köşe vakasını ekleyerek düzeltebilirsiniz: eğer n> 2 başka s [: n]
Dave

1
       >>> info = lambda data: len(data)>10 and data[:10]+'...' or data
       >>> info('sdfsdfsdfsdfsdfsdfsdfsdfsdfsdfsdf')
           'sdfsdfsdfs...'
       >>> info('sdfsdf')
           'sdfsdf'
       >>> 

1
Lütfen cevabınızı açıklayınız?
Gwenc37

bu fonksiyonun benzer örneği def info2 (veri): eğer len (veri)> 10: veri döndür [[10] + '...' başka: işlevsel bir stilde isimsiz tasarımın veri lambda komutunu döndür ex = lambda x: x + 1 def eski (x): dönüş x + 1
Spouk

1

Dinamik olarak ayrılmış bir C dizesi gibi bir Python dizesini "kesemezsiniz". Python'daki dizeler değişmezdir. Yapabileceğiniz şey, diğer cevaplarda açıklandığı gibi bir dize dilimlemek ve yalnızca dilim ofsetleri ve adım tarafından tanımlanan karakterleri içeren yeni bir dize oluşturmaktır. Bazı (pratik olmayan) durumlarda, bu biraz can sıkıcı olabilir, örneğin görüşme dili olarak Python'u seçtiğinizde ve görüşmeci sizden bir dizeden yinelenen karakterleri kaldırmanızı ister. Hamuru.


1
info = data[:min(len(data), 75)

Yalnızca kod yanıtları genellikle düşük kalite olarak kabul edilir. Cevabınıza bir açıklama ekleyebilir misiniz?
Lemon Kazi

0

Normal bir ifadeye gerek yoktur, ancak kabul edilen yanıtta dize birleştirmesi yerine dize biçimlendirmesi kullanmak istersiniz.

Bu muhtemelen dizeyi data75 karakterde kısaltmanın en kanonik, Pythonic yoludur .

>>> data = "saddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddsaddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddsadddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
>>> info = "{}..".format(data[:75]) if len(data) > 75 else data
>>> info
'111111111122222222223333333333444444444455555555556666666666777777777788888...'

saddddddd...Dizenin nasıl dönüştüğünü komik buldum 111111...:) Yine de kopyala-yapıştır yazım hatası olduğunu biliyorum ve düzenli ifadeler konusunda sana katılıyorum.
akarilimano

0

İşte yeni bir String sınıfının parçası olarak yaptığım bir işlev ... Bir sonek eklemeye izin verir (eğer dize kırptıktan sonra boyutsa ve ekleyerek yeterince uzunsa da - mutlak boyutu zorlamanız gerekmez)

Etrafta birkaç şey değiştirme sürecindeydim, bu yüzden artık gerekli olmadığı ve üstte bir dönüş olduğu bazı işe yaramaz mantık maliyetleri var (örneğin, _truncate ... örneğin).

Ancak, verileri kesmek için hala iyi bir işlevdir ...

##
## Truncate characters of a string after _len'nth char, if necessary... If _len is less than 0, don't truncate anything... Note: If you attach a suffix, and you enable absolute max length then the suffix length is subtracted from max length... Note: If the suffix length is longer than the output then no suffix is used...
##
## Usage: Where _text = 'Testing', _width = 4
##      _data = String.Truncate( _text, _width )                        == Test
##      _data = String.Truncate( _text, _width, '..', True )            == Te..
##
## Equivalent Alternates: Where _text = 'Testing', _width = 4
##      _data = String.SubStr( _text, 0, _width )                       == Test
##      _data = _text[  : _width ]                                      == Test
##      _data = ( _text )[  : _width ]                                  == Test
##
def Truncate( _text, _max_len = -1, _suffix = False, _absolute_max_len = True ):
    ## Length of the string we are considering for truncation
    _len            = len( _text )

    ## Whether or not we have to truncate
    _truncate       = ( False, True )[ _len > _max_len ]

    ## Note: If we don't need to truncate, there's no point in proceeding...
    if ( not _truncate ):
        return _text

    ## The suffix in string form
    _suffix_str     = ( '',  str( _suffix ) )[ _truncate and _suffix != False ]

    ## The suffix length
    _len_suffix     = len( _suffix_str )

    ## Whether or not we add the suffix
    _add_suffix     = ( False, True )[ _truncate and _suffix != False and _max_len > _len_suffix ]

    ## Suffix Offset
    _suffix_offset = _max_len - _len_suffix
    _suffix_offset  = ( _max_len, _suffix_offset )[ _add_suffix and _absolute_max_len != False and _suffix_offset > 0 ]

    ## The truncate point.... If not necessary, then length of string.. If necessary then the max length with or without subtracting the suffix length... Note: It may be easier ( less logic cost ) to simply add the suffix to the calculated point, then truncate - if point is negative then the suffix will be destroyed anyway.
    ## If we don't need to truncate, then the length is the length of the string.. If we do need to truncate, then the length depends on whether we add the suffix and offset the length of the suffix or not...
    _len_truncate   = ( _len, _max_len )[ _truncate ]
    _len_truncate   = ( _len_truncate, _max_len )[ _len_truncate <= _max_len ]

    ## If we add the suffix, add it... Suffix won't be added if the suffix is the same length as the text being output...
    if ( _add_suffix ):
        _text = _text[ 0 : _suffix_offset ] + _suffix_str + _text[ _suffix_offset: ]

    ## Return the text after truncating...
    return _text[ : _len_truncate ]

1
her bir argüman ve değişken tüm alt çizgiler ile ne?
Nicholas Hamilton

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.