it-swarm.com.de

String-Vergleichstechnik, die von Python verwendet wird

Ich frage mich, wie Python einen Stringvergleich durchführt, genauer gesagt, wie das Ergebnis bestimmt wird, wenn ein Operator mit weniger als (<) oder größer als (>) verwendet wird.

Wenn ich zum Beispiel print('abc' < 'bac') stelle, bekomme ich True. Ich verstehe, dass er die entsprechenden Zeichen in der Zeichenfolge vergleicht, es ist jedoch unklar, warum es aus Gründen der mangelnden besseren Bezeichnung "Gewicht" darauf kommt, dass a in der ersten Zeichenfolge weniger als b (erste Position) ist die Tatsache, dass a in der zweiten Saite kleiner als b ist (zweite Position).

43
davelupt

Aus den docs :

Der Vergleich verwendet lexikografisch Bestellung: zuerst die ersten beiden Artikel werden verglichen, und wenn sie sich unterscheiden, __. bestimmt das Ergebnis von Vergleich; wenn sie gleich sind, die Die nächsten zwei Elemente werden verglichen, und so ein, bis eine der Sequenzen .__ ist. erschöpft.

Ebenfalls:

Die lexikografische Reihenfolge für Zeichenfolgen verwendet die Unicode-Codepunktnummer, um einzelne Zeichen zu sortieren.

oder auf Python 2 :

Die lexikografische Reihenfolge für Zeichenfolgen verwendet die Reihenfolge der Zeichen ASCII für einzelne Zeichen.

Als Beispiel:

>>> 'abc' > 'bac'
False
>>> ord('a'), ord('b')
(97, 98)

Das Ergebnis False wird zurückgegeben, sobald festgestellt wird, dass a kleiner als b ist. Die weiteren Elemente werden nicht verglichen (wie Sie für die zweiten Elemente sehen können: b> a ist True).

Beachten Sie Klein- und Großbuchstaben:

>>> [(x, ord(x)) for x in abc]
[('a', 97), ('b', 98), ('c', 99), ('d', 100), ('e', 101), ('f', 102), ('g', 103), ('h', 104), ('i', 105), ('j', 106), ('k', 107), ('l', 108), ('m', 109), ('n', 110), ('o', 111), ('p', 112), ('q', 113), ('r', 114), ('s', 115), ('t', 116), ('u', 117), ('v', 118), ('w', 119), ('x', 120), ('y', 121), ('z', 122)]
>>> [(x, ord(x)) for x in abc.upper()]
[('A', 65), ('B', 66), ('C', 67), ('D', 68), ('E', 69), ('F', 70), ('G', 71), ('H', 72), ('I', 73), ('J', 74), ('K', 75), ('L', 76), ('M', 77), ('N', 78), ('O', 79), ('P', 80), ('Q', 81), ('R', 82), ('S', 83), ('T', 84), ('U', 85), ('V', 86), ('W', 87), ('X', 88), ('Y', 89), ('Z', 90)]
69
user225312

Der Vergleich von Python-Zeichenfolgen ist lexikografisch:

Aus Python-Dokumenten: http://docs.python.org/reference/expressions.html

Zeichenketten werden lexikographisch anhand der numerischen Äquivalente (das Ergebnis der integrierten Funktion ord ()) ihrer Zeichen verglichen. Unicode- und 8-Bit-Zeichenfolgen sind in diesem Verhalten vollständig interoperabel.

In Ihrem Beispiel steht 'abc' < 'bac', 'a' steht numerisch (in ASCII - und Unicode-Darstellungen) vor (kleiner als) 'b', sodass der Vergleich genau dort endet.

8
wkl

Python und fast jede andere Computersprache verwenden die gleichen Prinzipien wie (hoffentlich), die Sie verwenden würden, wenn Sie ein Wort in einem gedruckten Wörterbuch finden:

(1) Abhängig von der verwendeten menschlichen Sprache haben Sie eine Vorstellung von der Reihenfolge der Zeichen: 'a' <'b' <'c' etc 

(2) Das erste Zeichen hat mehr Gewicht als das zweite Zeichen: 'az' <'za' (ob die Sprache von links nach rechts oder von rechts nach links oder von Boustrophedon geschrieben wird, ist ziemlich irrelevant) 

(3) Wenn zum Testen die Zeichen ausgehen, ist die kürzere Zeichenfolge kleiner als die längere Zeichenfolge: 'foo' <'food'

In einer Computersprache ist der "Begriff der Zeichenreihenfolge" normalerweise eher primitiv: Jedes Zeichen hat eine von der Sprache unabhän- gige Nummer ord(character), und die Zeichen werden anhand dieser Nummer verglichen und sortiert. Oft ist diese Reihenfolge nicht auf die menschliche Sprache des Benutzers abgestimmt, und dann müssen Sie sich mit "Sortieren" befassen, einem unterhaltsamen Thema.

7
John Machin

Schauen Sie sich auch Wie sortiere ich Unicode-Zeichenfolgen in Python alphabetisch? an, in dem es um das Sortieren von Regeln geht, die vom Unicode-Kollatierungsalgorithmus vorgegeben werden ( http://www.unicode.org/ reports/tr10 / ).

Um auf den Kommentar zu antworten

Was? Wie kann die Reihenfolge anders als von links nach rechts definiert werden?

von S.Lott gibt es ein berühmtes Gegenbeispiel zum Sortieren der französischen Sprache. Es geht um Akzente: In der Tat könnte man sagen, dass die Buchstaben im Französischen von links nach rechts und die Akzente von rechts nach links sortiert sind. Hier ist das Gegenbeispiel: Wir haben e <é und o <ô, daher würden Sie erwarten, dass die Wörter cote, coté, côte, côté als cote <coté <côte <côté sortiert werden. Nun, das ist nicht das, was passiert, in der Tat haben Sie: cote <côte <coté <côté, dh wenn wir "c" und "t" entfernen, erhalten wir oe <ôe <oé <ôé, was genau richtig ist Bestellung.

Und noch eine letzte Bemerkung: Sie sollten nicht über von links nach rechts und von rechts nach links sprechen sortieren sondern über vorwärts und rückwärts sortieren.

In der Tat gibt es Sprachen, die von rechts nach links geschrieben sind, und wenn Sie glauben, Arabisch und Hebräisch seien von rechts nach links sortiert , sind Sie möglicherweise von einem grafischen Standpunkt aus richtig Ansicht, aber Sie sind auf der logischen Ebene falsch!

In der Tat berücksichtigt Unicode Zeichenfolgen, die in logischer Reihenfolge codiert sind, und die Schreibrichtung ist ein Phänomen, das auf Glyphenebene auftritt. Mit anderen Worten, auch wenn im Wort Wordלום der Buchstabe shin rechts vom lamed erscheint, tritt er logischerweise auf davor . Um dieses Wort zu sortieren, wird man zuerst das Schienbein betrachten, dann das Gelähmte, dann das Waw, dann das Mem, und dies ist eine vorwärtsgerichtete Reihenfolge (obwohl hebräisch ist) geschrieben von rechts nach links), während französische Akzente rückwärts sortiert sind (obwohl Französisch von links nach rechts geschrieben ist).

3
yannis

Dies ist eine lexikografische Reihenfolge . Es bringt die Dinge einfach in die Reihenfolge der Wörterbücher. 

3

Ein reines Python-Äquivalent für Zeichenfolgenvergleiche wäre:

def less(string1, string2):
    # Compare character by character
    for idx in range(min(len(string1), len(string2))):
        # Get the "value" of the character
        ordinal1, ordinal2 = ord(string1[idx]), ord(string2[idx])
        # If the "value" is identical check the next characters
        if ordinal1 == ordinal2:
            continue
        # If it's smaller we're finished and can return True
        Elif ordinal1 < ordinal2:
            return True
        # If it's bigger we're finished and return False
        else:
            return False
    # We're out of characters and all were equal, so the result depends on the length
    # of the strings.
    return len(string1) < len(string2)

Diese Funktion macht das Äquivalent der echten Methode ( Python 3.6 und Python 2.7 ) nur viel langsamer. Beachten Sie auch, dass die Implementierung nicht genau "Pythonic" ist und nur für <-Vergleiche funktioniert. Es soll nur veranschaulichen, wie es funktioniert. Ich habe nicht überprüft, ob der Pythons-Vergleich für kombinierte Unicode-Zeichen funktioniert.

Eine allgemeinere Variante wäre:

from operator import lt, gt

def compare(string1, string2, less=True):
    op = lt if less else gt
    for char1, char2 in Zip(string1, string2):
        ordinal1, ordinal2 = ord(char1), ord(char1)
        if ordinal1 == ordinal2:
            continue
        Elif op(ordinal1, ordinal2):
            return True
        else:
            return False
    return op(len(string1), len(string2))
2
MSeifert

Strings werden verglichen lexikographisch unter Verwendung der numerischen Äquivalente (das Ergebnis der eingebauten Funktion ord ()) ihrer Zeichen. Unicode- und 8-Bit-Zeichenfolgen sind in diesem Verhalten vollständig interoperabel.

1
Senthil Kumaran

Hier ist ein Beispielcode, der zwei Zeichenketten lexikographisch vergleicht.

  a = str(input())
  b = str(input())
  if 1<=len(a)<=100 and 1<=len(b)<=100:
    a = a.lower()
    b = b.lower()
    if a > b:
       print('1')
    Elif a < b:
       print( '-1')
    Elif a == b:
       print('0') 

für verschiedene Eingänge sind die Ausgänge

1- abcdefg
   abcdeff
   1

2- abc
   Abc
   0

3- abs
   AbZ
  -1
0
Dlucidone