1416 Stimmen

Versteckte Funktionen von Python

739voto

Thomas Wouters Punkte 124421

Verkettung von Vergleichsoperatoren:

>>> x = 5
>>> 1 < x < 10
True
>>> 10 < x < 20 
False
>>> x < 10 < x*10 < 100
True
>>> 10 > x <= 9
True
>>> 5 == x > 4
True

Falls Sie denken, es tut sich was 1 < x was zu folgendem Ergebnis führt True und vergleicht dann True < 10 die auch True dann nein, das ist wirklich nicht das, was passiert (siehe das letzte Beispiel). 1 < x and x < 10 y x < 10 and 10 < x * 10 and x*10 < 100 , aber mit weniger Tipparbeit und jeder Begriff wird nur einmal ausgewertet.

0 Stimmen

Ist nicht 10 > x <= 9 dasselbe wie x <= 9 (mit Ausnahme von überladenen Operatoren, das heißt)

1 Stimmen

Ja, natürlich. Das war nur ein Beispiel für die Vermischung verschiedener Betreiber.

19 Stimmen

Dies gilt auch für andere Vergleichsoperatoren, weshalb man sich manchmal wundert, warum Code wie (5 in [5] ist wahr) falsch ist (aber es ist unpythonisch, explizit gegen Boolesche Werte wie diesen zu testen).

511voto

BatchyX Punkte 4796

Holen Sie sich den Python Regex Parse Tree, um Ihre Regex zu debuggen.

Reguläre Ausdrücke sind eine großartige Funktion von Python, aber die Fehlersuche kann mühsam sein, und es ist nur allzu leicht, eine Regex falsch zu verstehen.

Glücklicherweise kann Python den Regex-Parse-Baum ausgeben, indem es das undokumentierte, experimentelle, versteckte Flag re.DEBUG (eigentlich 128) auf re.compile .

>>> re.compile("^\[font(?:=(?P<size>[-+][0-9]{1,2}))?\](.*?)[/font]",
    re.DEBUG)
at at_beginning
literal 91
literal 102
literal 111
literal 110
literal 116
max_repeat 0 1
  subpattern None
    literal 61
    subpattern 1
      in
        literal 45
        literal 43
      max_repeat 1 2
        in
          range (48, 57)
literal 93
subpattern 2
  min_repeat 0 65535
    any None
in
  literal 47
  literal 102
  literal 111
  literal 110
  literal 116

Sobald Sie die Syntax verstanden haben, können Sie Ihre Fehler erkennen. Hier können wir sehen, dass ich vergessen habe, das [] en [/font] .

Natürlich können Sie es mit beliebigen Flags kombinieren, z. B. mit kommentierten Regexen:

>>> re.compile("""
 ^              # start of a line
 \[font         # the font tag
 (?:=(?P<size>  # optional [font=+size]
 [-+][0-9]{1,2} # size specification
 ))?
 \]             # end of tag
 (.*?)          # text between the tags
 \[/font\]      # end of the tag
 """, re.DEBUG|re.VERBOSE|re.DOTALL)

3 Stimmen

Allerdings ist das Parsen von HTML mit regulären Ausdrücken langsam und mühsam. Selbst das eingebaute 'html'-Parser-Modul verwendet keine Regexe, um die Arbeit zu erledigen. Und wenn Ihnen das html-Modul nicht zusagt, gibt es jede Menge XML/HTML-Parser-Module, die die Arbeit erledigen, ohne dass Sie das Rad neu erfinden müssen.

0 Stimmen

Ein Link zur Dokumentation der Ausgabesyntax wäre sehr hilfreich.

1 Stimmen

Dies sollte ein offizieller Teil von Python sein, nicht experimentell... RegEx ist immer knifflig und die Möglichkeit, zu verfolgen, was passiert, ist wirklich hilfreich.

459voto

Dave Punkte 479

aufzählen.

Wickeln Sie eine iterable mit enumerate und es wird das Element zusammen mit seinem Index zu liefern.

Zum Beispiel:

>>> a = ['a', 'b', 'c', 'd', 'e']
>>> for index, item in enumerate(a): print index, item
...
0 a
1 b
2 c
3 d
4 e
>>>

Referenzen:

0 Stimmen

Ich denke, es ist in Python3 veraltet

45 Stimmen

Und die ganze Zeit habe ich auf diese Weise kodiert: for i in range(len(a)): ... und dann mit a[i], um das aktuelle Element zu erhalten.

4 Stimmen

@Berry Tsakala: Soweit ich weiß, ist sie nicht veraltet.

418voto

freespace Punkte 16029

Erstellen von Generatorobjekten

Wenn Sie schreiben

x=(n for n in foo if bar(n))

können Sie den Generator herausholen und ihn x zuweisen. Das bedeutet, dass Sie jetzt

for n in x:

Dies hat den Vorteil, dass Sie keine Zwischenspeicherung benötigen, die Sie bei der Verwendung von

x = [n for n in foo if bar(n)]

In einigen Fällen kann dies zu einer erheblichen Beschleunigung führen.

Sie können viele if-Anweisungen an das Ende des Generators anhängen und so verschachtelte for-Schleifen nachbilden:

>>> n = ((a,b) for a in range(0,2) for b in range(4,6))
>>> for i in n:
...   print i 

(0, 4)
(0, 5)
(1, 4)
(1, 5)

0 Stimmen

Sie könnten dafür auch ein verschachteltes Listenverständnis verwenden, oder?

54 Stimmen

Besonders hervorzuheben sind die Einsparungen beim Speicher-Overhead. Die Werte werden bei Bedarf berechnet, so dass Sie nie das gesamte Ergebnis der Listenverarbeitung im Speicher haben. Dies ist besonders dann wünschenswert, wenn Sie später nur über einen Teil des Listenverständnisses iterieren.

0 Stimmen

Ich verwende ifilter für diese Art von Dingen: docs.python.org/library/itertools.html#itertools.ifilter

352voto

mbac32768 Punkte 11205

iter() kann ein aufrufbares Argument annehmen

Zum Beispiel:

def seek_next_line(f):
    for c in iter(lambda: f.read(1),'\n'):
        pass

El iter(callable, until_value) Funktion ruft wiederholt callable und liefert sein Ergebnis, bis until_value zurückgegeben wird.

0 Stimmen

Als Python-Neuling, können Sie bitte erklären, warum die lambda Stichwort ist hier notwendig?

0 Stimmen

@SiegeX ohne das Lambda würde f.read(1) ausgewertet (und eine Zeichenkette zurückgegeben), bevor es an die iter-Funktion übergeben wird. Stattdessen erstellt das Lambda eine anonyme Funktion und übergibt diese an iter.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X