Vraag Verborgen kenmerken van Python [gesloten]


Wat zijn de minder bekende maar nuttige functies van de programmeertaal Python?

  • Probeer de antwoorden op de Python-kern te beperken.
  • Eén functie per antwoord.
  • Geef een voorbeeld en een korte beschrijving van de functie, niet alleen een link naar documentatie.
  • Label de functie met een titel als eerste regel.

Snelle links naar antwoorden:


1420


oorsprong


antwoorden:


Ketenvergelijkingsoperatoren:

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

Voor het geval je denkt dat het aan het doen is 1 < x, wat eruit komt als Trueen dan vergelijken True < 10, wat ook zo is True, nee dan, dat is echt niet wat er gebeurt (zie het laatste voorbeeld.) Het is echt vertalen in 1 < x and x < 10, en x < 10 and 10 < x * 10 and x*10 < 100, maar met minder typen en elke term wordt slechts eenmaal geëvalueerd.


741



Haal de python regex parse tree om je regex te debuggen.

Reguliere expressies zijn een geweldige eigenschap van python, maar het kan lastig zijn om ze te debuggen, en het is maar al te gemakkelijk om een ​​regex verkeerd te krijgen.

Gelukkig kan python de regex-parseboom afdrukken door de ongedocumenteerde, experimentele, verborgen vlag over te dragen re.DEBUG (eigenlijk, 128) voor 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

Zodra u de syntaxis begrijpt, kunt u uw fouten herkennen. Daar kunnen we zien dat ik vergat te ontsnappen aan de [] in [/font].

Natuurlijk kun je het combineren met elke vlag die je wilt, zoals regexes met commentaar:

>>> 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)

512



opsommen

Wikkel een iterabele met enumerate en het levert het item samen met zijn index.

Bijvoorbeeld:


>>> 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
>>>

Referenties:


460



Generators-objecten maken

Als je schrijft

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

je kunt de generator eruit halen en deze aan x toewijzen. Nu betekent dit dat u het kunt doen

for n in x:

Het voordeel hiervan is dat u geen tussentijdse opslag nodig heeft, die u nodig zou hebben als u dat deed

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

In sommige gevallen kan dit tot een aanzienlijke versnelling leiden.

U kunt vele if-instructies toevoegen aan het einde van de generator door in principe geneste for-lussen te repliceren:

>>> 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)

419



iter () kan een opvraagbaar argument aannemen

Bijvoorbeeld:

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

De iter(callable, until_value) herhaal herhaaldelijk oproepen callable en levert zijn resultaat op tot until_value wordt teruggestuurd.


353



Wees voorzichtig met veranderbare standaardargumenten

>>> def foo(x=[]):
...     x.append(1)
...     print x
... 
>>> foo()
[1]
>>> foo()
[1, 1]
>>> foo()
[1, 1, 1]

Gebruik in plaats daarvan een sentinelwaarde die staat voor "not given" en vervang deze standaard door de veranderbare waarde die u wilt:

>>> def foo(x=None):
...     if x is None:
...         x = []
...     x.append(1)
...     print x
>>> foo()
[1]
>>> foo()
[1]

339



Waarden verzenden naar generatorfuncties. Bijvoorbeeld met deze functie:

def mygen():
    """Yield 5 until something else is passed back via send()"""
    a = 5
    while True:
        f = (yield a) #yield a and possibly get f in return
        if f is not None: 
            a = f  #store the new value

Jij kan:

>>> g = mygen()
>>> g.next()
5
>>> g.next()
5
>>> g.send(7)  #we send this back to the generator
7
>>> g.next() #now it will yield 7 until we send something else
7

317