Python schneidet eine lange Zeichenfolge ab

244

Wie schneidet man eine Zeichenfolge in Python auf 75 Zeichen ab?

So wird es in JavaScript gemacht:

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

Antworten:

424
info = (data[:75] + '..') if len(data) > 75 else data
Marcelo Cantos
quelle
58
Ich würde die Bedingung vielleicht ändern len(data) > 77, um die doppelten Punkte zu berücksichtigen (es ist sinnlos, nur das letzte Zeichen abzuschneiden, nur um es durch einen Punkt zu ersetzen).
hasen
5
@hasenj: Das würde nicht dem ursprünglichen Code entsprechen, aber es ist ein guter Vorschlag, auf den ich an erster Stelle hätte hinweisen sollen.
Marcelo Cantos
2
Beachten Sie, dass die enthaltenen Parens natürlich optional sind.
Taylor Edmiston
10
@TaylorEdmiston Stimmt, aber sie sind sehr hilfreich für diejenigen, die sich nicht an alle Vorrangregeln für die 5–10 Sprachen erinnern, die sie täglich verwenden.
Marcelo Cantos
2
@ Anthony eine Scheibe
Marcelo Cantos
126

Noch kürzer:

info = data[:75] + (data[75:] and '..')
stanlekub
quelle
2
Lustiger Ansatz, um es zu tun. Obwohl es immer noch ein zusammengesetzter Einzeiler ist. ^^
Fröhlich
3
Hat diese Lösung nicht 77 Zeichen, wenn Sie das '..' einfügen?
Mark Chackerian
führt dies nicht zwei Slice-Operationen aus? Ich frage mich, wie dies im Vergleich zu stackoverflow.com/a/52279347/1834057 funktioniert , wenn die Leistung entscheidend ist
Nicholas Hamilton
1
Sicher, schöne originelle Antwort, aber Marcelos Antwort ist besser, da sie expliziter und somit lesbar (und damit pythonisch) ist.
Sitnarf
114

Noch prägnanter:

data = data[:75]

Wenn es weniger als 75 Zeichen sind, wird keine Änderung vorgenommen.

Neil
quelle
9
Vermutlich möchte er eine Ellipse anhängen, wenn die Zeichenfolge abgeschnitten ist.
FogleBird
4
Du hast recht - das habe ich nie bemerkt. Ich kann mir keinen besseren Weg vorstellen, dies zu tun als andere Antworten.
neil
82

Wenn Sie Python 3.4+ verwenden, können Sie Folgendes textwrap.shortenaus der Standardbibliothek verwenden:

Reduzieren Sie den angegebenen Text und schneiden Sie ihn ab, damit er in die angegebene Breite passt.

Zuerst wird das Leerzeichen im Text reduziert (alle Leerzeichen werden durch einzelne Leerzeichen ersetzt). Wenn das Ergebnis in die Breite passt, wird es zurückgegeben. Andernfalls werden am Ende genügend Wörter entfernt, sodass die verbleibenden Wörter plus Platzhalter in die Breite passen:

>>> textwrap.shorten("Hello  world!", width=12)
'Hello world!'
>>> textwrap.shorten("Hello  world!", width=11)
'Hello [...]'
>>> textwrap.shorten("Hello world", width=10, placeholder="...")
'Hello...'
Bora M. Alper
quelle
8
Es scheint seine Hosen an wirklich langen Saiten (keine Leerzeichen) zu scheißen und gibt nur die Auslassungspunkte aus.
ElBradford
5
@elBradford (und interessierte andere): Das liegt daran, dass Wörtershorten() abgeschnitten werden , keine einzelnen Zeichen. Ich habe gesucht, aber es scheint keine Möglichkeit zu geben , einzelne Zeichen und keine Wörter zu konfigurieren oder eine Instanz zu beschneiden. shorten()TextWrapper
Acsor
Und es hat den nervigen Nebeneffekt, Zeilenumbrüche zu entfernen
Havlock
Dies löst die Frage von OP nicht. Es wird wortweise abgeschnitten und sogar Leerzeichen entfernt.
Florian Wendelborn
9

Sie könnten diesen Einzeiler verwenden:

data = (data[:75] + '..') if len(data) > 75 else data
phoenix24
quelle
2
Wie [:n]heißt es, damit ich es in der Dokumentation nachschlagen kann?
Oldboy
9

Mit Regex:

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

Lange Zeichenfolgen werden abgeschnitten:

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

Kürzere Zeichenfolgen werden niemals abgeschnitten:

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

Auf diese Weise können Sie auch den mittleren Teil der Saite "schneiden", was in einigen Fällen schöner ist:

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

>>> data="11111111112222222222333333333344444444445555555555666666666677777777778888888888"
>>> re.sub(r'^(.{5}).*(.{5})$', '\g<1>...\g<2>', data)
'11111...88888'
Davide Guerri
quelle
Nun
Warum würden Sie Regex für einen so einfachen Fall verwenden?
Bora M. Alper
5

Diese Methode verwendet keine, wenn:

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

Sassan
quelle
4
Ich habe es nur geschrieben, um zu zeigen, dass es möglich ist. Es ist gegen die Lesbarkeitsphilosophie von Python. Es hat keinen Leistungsvorteil im Vergleich zu anderen "if" -basierten Methoden. Ich benutze es nie und ich schlage nicht vor, dass Sie es auch benutzen.
Sassan
4
limit = 75
info = data[:limit] + '..' * (len(data) > limit)
Hallo Auf Wiedersehen
quelle
1
Dies ist die eleganteste Lösung. Zusätzlich würde ich das Zeichenlimit (in diesem Fall 75) in eine Variable extrahieren , um Inkonsistenzen zu vermeiden. limit = 75; info = data[:limit] + '..' * (len(data) > limit)
Ekauffmann
3

Noch eine andere Lösung. Mit Trueund FalseSie erhalten am Ende ein kleines Feedback zum Test.

data = {True: data[:75] + '..', False: data}[len(data) > 75]
Der wahre Bugeater
quelle
2

Dies nur in:

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...
Dansalmo
quelle
Bei allen vorherigen Antworten wird nicht berücksichtigt, was das OP wirklich wollte - eine Ausgabezeichenfolge mit nicht mehr als 75 Zeichen. Ein großes Lob für das Verständnis des Programmierprinzips "Mach nicht was ich sage, mach was ich will". Der Vollständigkeit halber können Sie den Eckfall von n <3 durch Anhängen beheben: wenn n> 2 sonst s [: n]
Dave
1
       >>> info = lambda data: len(data)>10 and data[:10]+'...' or data
       >>> info('sdfsdfsdfsdfsdfsdfsdfsdfsdfsdfsdf')
           'sdfsdfsdfs...'
       >>> info('sdfsdf')
           'sdfsdf'
       >>> 
Spouk
quelle
1
Bitte erläutern Sie Ihre Antwort?
Gwenc37
ähnliches Beispiel für diese Funktion def info2 (Daten): wenn len (Daten)> 10: Daten zurückgeben [: 10] + '...' sonst: Daten zurückgeben Lambda-Anweisung des namenlosen Designs in einem funktionalen Stil ex = Lambda x: x + 1 def ex (x): Rückgabe x + 1
Spouk
1

Sie können eine Python-Zeichenfolge nicht wie eine dynamisch zugewiesene C-Zeichenfolge "abschneiden". Zeichenfolgen in Python sind unveränderlich. Sie können eine Zeichenfolge wie in anderen Antworten beschrieben in Scheiben schneiden und eine neue Zeichenfolge erstellen, die nur die Zeichen enthält, die durch die Schichtversätze und den Schritt definiert sind. In einigen (nicht praktischen) Fällen kann dies etwas ärgerlich sein, z. B. wenn Sie Python als Interviewsprache auswählen und der Interviewer Sie auffordert, doppelte Zeichen aus einer vorhandenen Zeichenfolge zu entfernen. Doh.

Dave
quelle
1
info = data[:min(len(data), 75)
Jesse
quelle
Nur-Code-Antworten gelten im Allgemeinen als minderwertig. Könnten Sie Ihrer Antwort eine Erklärung hinzufügen?
Lemon Kazi
0

Es ist kein regulärer Ausdruck erforderlich, Sie möchten jedoch die Zeichenfolgenformatierung anstelle der Zeichenfolgenverkettung in der akzeptierten Antwort verwenden.

Dies ist wahrscheinlich die kanonischste, pythonischste Methode, um die Zeichenfolge datamit 75 Zeichen abzuschneiden .

>>> data = "saddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddsaddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddsadddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
>>> info = "{}..".format(data[:75]) if len(data) > 75 else data
>>> info
'111111111122222222223333333333444444444455555555556666666666777777777788888...'
Adam Nelson
quelle
Ich fand es lustig, wie sich Ihre saddddddd...Zeichenfolge verwandelt 111111...:) Ich weiß, dass es sich um einen Tippfehler handelt, und ich stimme Ihnen in Bezug auf reguläre Ausdrücke zu.
Akarilimano
0

Hier ist eine Funktion, die ich als Teil einer neuen String-Klasse erstellt habe ... Sie ermöglicht das Hinzufügen eines Suffix (wenn der String nach dem Zuschneiden die Größe hat und das Hinzufügen lang genug ist - obwohl Sie die absolute Größe nicht erzwingen müssen).

Ich war dabei, ein paar Dinge zu ändern, so dass es einige nutzlose Logikkosten gibt (wenn _truncate ... zum Beispiel), bei denen es nicht mehr notwendig ist und es eine Rendite an der Spitze gibt ...

Aber es ist immer noch eine gute Funktion zum Abschneiden von Daten ...

##
## 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 ]
Acecool
quelle
1
Was ist mit all den Unterstrichen in jedem einzelnen Argument und jeder Variablen?
Nicholas Hamilton
0
info = data[:75] + ('..' if len(data) > 75 else '')
Hallo Auf Wiedersehen
quelle