Schreiben Sie Python-ähnlichen Code

Auf Youtube erklärt Raymond Hettinger (Python Core Developper) häufige Fehler und korrektes Schreiben in Python Video. Ich habe? V = OSGv2VnC0go) gefunden, also werde ich es zusammenfassen. Im Video verwende ich hauptsächlich python2 als Beispiel (da es sich um ein 2013er Video handelt), aber hier habe ich es so weit wie möglich in python3 konvertiert. Möglicherweise befindet es sich bereits im alten Stil. Bitte überprüfen Sie es, bevor Sie es verwenden.

Loop

Einfache Schleife

Schlechtes Beispiel


for i in [0, 1, 2, 3, 4, 5]:
  print(i**2)

Speichern Sie die gesamte Liste. ↓

Gutes Beispiel


for i in range(6):
  print(i**2)

Da "Bereich" einzeln als Iterator generiert wird, wird kein Speicher verschwendet.

In python2 ist range eine Liste und xrange ein itertor In Python3 ist range ein Iterator (der Name von xrange in python2 hat sich geändert)

Listenschleife

Schlechtes Beispiel


colors = ['red', 'green', 'blue', 'yellow']

for i in range(len(colors)):
  print(colors[i])

Gutes Beispiel


colors = ['red', 'green', 'blue', 'yellow']

for color in colors:
  print(color)

Das Schreiben unten ist schneller

Umkehrschleife

Schlechtes Beispiel


colors = ['red', 'green', 'blue', 'yellow']

for i in range(len(colors)-1, -1, -1):
  print(colors[i])

Gutes Beispiel


colors = ['red', 'green', 'blue', 'yellow']

for color in reversed(colors):
  print(color)

Ich möchte auch einen Index bekommen

Schlechtes Beispiel


colors = ['red', 'green', 'blue', 'yellow']

for i in range(len(colors)):
  print(i, '--->', colors[i])

Gutes Beispiel


colors = ['red', 'green', 'blue', 'yellow']

for i, color in enumerate(colors):
  print(i, '--->', color)

Schleifen Sie zwei Listen gleichzeitig

Schlechtes Beispiel


names = ['raymond', 'rachel', 'matthew']
colors = ['red', 'green', 'blue', 'yellow']

n = min(len(names), len(colors))
for i in range(n):
  print(names[i], '--->'. colors[i]

Gutes Beispiel


names = ['raymond', 'rachel', 'matthew']
colors = ['red', 'green', 'blue', 'yellow']

for name, color in zip(names, colors):
  print(name, '--->', color)

Wenn Iteratoren unterschiedlicher Länge in die Zip-Datei eingegeben werden, werden sie an der kürzeren ausgerichtet. itertools.zip_longest, um sich an der längeren auszurichten

In python2 generiert zip eine Liste ( izip ist ein Iterator), In python3 generiert zip einen Iterator

Benutzerdefinierte Sortierung

Schlechtes Beispiel


colors = ['red', 'green', 'blue', 'yellow']

def compare_length(c1, c2):
  if len(c1) < len(c2):
    return -1
  elif len(c1) > len(c2):
    return 1
  else:
    return 0

print(sorted(colors, cmp=compare_length)

Gutes Beispiel


colors = ['red', 'green', 'blue', 'yellow']

print(sorted(colors, key=len))

** Ist das Sortieren nach Schlüssel ausreichend? ** ** ** In einigen Fällen reicht es nicht aus, aber in den meisten Fällen ist es in Ordnung. (SQL sortiert viel, aber durch Schlüsselsortierung.)

Stoppen Sie die Schleife mit dem Sentinel-Wert

Schlechtes Beispiel


blocks = []
while True:
  block = f.read(32)
  if block == '':
    break
  blocks.append(block)

Gutes Beispiel


blocks = []

for block in iter(functool.partial(f.read, 32), ''):
  blocks.append(block)

partiell ist unangenehm, aber der Vorteil, als Iterator damit umgehen zu können, ist groß Es ist besser, den Sentinel-Wert zu vermeiden

Verlassen Sie die Schleife je nach Zustand

Schlechtes Beispiel


def find(seq, target):
  found = False
  for i, value in enumerate(seq):
    if value == target:
      found = True
      break
  if not found:
    return -1
  return i

Beispiel, wenn Sie ein Flag verwenden müssen (found) ↓

Gutes Beispiel


def find(seq, target):
  for i, value in enumerate(seq):
    if value == target:
      break
  else:
    return -1
  return i

Wenn kein Einbruch für erfolgt, wird die else-Anweisung ausgeführt. Er bedauert, dass er es "nobreak" hätte nennen sollen, anstatt sonst.

Dictionary

Loop-Wörterbuchschlüssel

d = {'matthew': 'blue', 'rachel': 'green', 'raymond': 'red'}

for k in d:
  print(k)

↑ Wenn Sie Änderungen am Wörterbuch vornehmen, passiert etwas Seltsames

d = {'matthew': 'blue', 'rachel': 'green', 'raymond': 'red'}

for k in d.keys():
  if k.startswith('r'):
    del d[k]

d.keys () erstellt im Voraus eine Kopie der Liste, damit Sie das Wörterbuch ändern können

Schleifenschlüssel und Wert

Schlechtes Beispiel


d = {'matthew': 'blue', 'rachel': 'green', 'raymond': 'red'}

for k in d:
  print(k, '--->', d[k])

Gutes Beispiel


d = {'matthew': 'blue', 'rachel': 'green', 'raymond': 'red'}

for k, v in d.items():
  print(k, '--->', v)

Erstellen Sie ein Wörterbuch aus einer Liste

names = ['raymond', 'rachel', 'matthew']
colors = ['red', 'green', 'blue']

d = dict(zip(names, colors))

Zählen Sie die Anzahl der Vorkommen in der Liste

Ineffiziente Methode


colors = ['red', 'green', 'red', 'blue', 'green', 'red']

d = {}
for color in colors:
  if color in d:
    d[color] = 0
  d[color] += 1

Der richtige Weg


d = {}
for color in colors:
  d[color] = d.get(color, 0) + 1

Neueste Methode


d = defaultdict(int)
for color in colors:
  d[color] += 1

Gruppieren Sie die Liste

Schlechtes Beispiel


names = ['raymond', 'raychel', 'matthew', 'roger', 'betty', 'melisa', 'judith', 'charlie']

d = {}
for name in names:
  key = len(name)
  if key not in d:
    d[key] = []
  d[key].append(name)

Der richtige Weg


d = {}
for name in names:
  key = len(name)
  d.setdefault(key, []).append(name)

Neueste Methode


d = defaultdict(list)
for name in names:
  key = len(name)
  d[key].append(name)

get wird dem Wörterbuch nicht zugewiesen. setdefault ersetzt

Kleben Sie mehrere Wörterbücher zusammen

Schlechtes Beispiel


defaults = {'color': 'red', 'user': 'guest'}
parser = argparse.ArgumentParser()
parser.add_argument('-u', '--user')
parser.add_argument('-c', '--color')
namespace = parser.parse_args([])
command_line_args = {k: v for k, v in vars(namespace).items() if v}

d = defaults.copy()
d.update(os.environ)
d.update(command_line_args)

Eine große Anzahl von Wörterbüchern wird kopiert ↓

Gutes Beispiel


d = collections.ChainMap(command_line_args, os.environ, defaults)

Behalten Sie das ursprüngliche Wörterbuch bei, wie es ist, ohne es zu kopieren

Verbesserte Lesbarkeit des Codes

Funktionsschlüsselwortargument

Schlechtes Beispiel


twitter_search('@obama', False, 20, True)

Ich verstehe die Bedeutung des Arguments nicht ↓

Gutes Beispiel


twitter_search('@obama', retweets=False, numtweets=20, popular=True)

NamedTuple

Schlechtes Beispiel


> doctest.testmod()
(0, 4)

Ich verstehe die Bedeutung von 0,4 nicht ↓

Gutes Beispiel


> doctest.testmod()
TestResults(failed=0, attempted=4)

TestResults ist

TestResults = namedtuple('TestResults', ['failed', 'attempted'])

Kann mit gemacht werden

Tupel auspacken

Schlechtes Beispiel


p = 'Raymond', 'Hettinger', 0x30, '[email protected]'

fname = p[0]
lname = p[1]
age = p[2]
email = p[3]

Gutes Beispiel


fname, lname, age, email = p

Aktualisieren Sie mehrere Status gleichzeitig

Schlechtes Beispiel


def fibonacci(n):
  x = 0
  y = 1
  for i in range(n):
    print(x)
    t = y
    y = x + y
    x = t

Es gibt einen Moment, in dem der Zustand während der Ausführung zusammenbricht. Es ist einfach, die Zeilenreihenfolge falsch zu verstehen ↓

Gutes Beispiel


def fibonacci(n):
  x, y = 0, 1
  for i in range(n):
    print(x)
    x, y = y, x+y

Dies ist näher am menschlichen Denken.

Effizienz (hohe Geschwindigkeit, Speicherplatzersparnis)

String-Verkettung

Schlechtes Beispiel


names = ['raymond', 'raychel', 'matthew', 'roger', 'betty', 'melisa', 'judith', 'charlie']

s = names[0]
for name in names[1:]:
  s += ', ' + name

Gutes Beispiel


', '.join(names)

Aktualisierungsliste

Schlechtes Beispiel


names = ['raymond', 'raychel', 'matthew', 'roger', 'betty', 'melisa', 'judith', 'charlie']

del names[0]
names.pop(0)
names.insert(0, 'mark')

langsam ↓

Gutes Beispiel


names = deque(['raymond', 'raychel', 'matthew', 'roger', 'betty', 'melisa', 'judith', 'charlie'])

del names[0]
names.popleft()
names.appendleft('mark')

schnell

Dekorateur und Kontextmanager

Zwischenspeicher

Schlechtes Beispiel


def web_lookup(url, saved={}):
  if url in saved:
    return saved[url]
  page = urlib.urlopen(url).read()
  saved[url] = page
  return page

Gutes Beispiel


@lru_cache()
def web_lookup(url):
  return urllib.urlopen(url).read()

Die Geschäftslogik und die Verwaltungslogik sind getrennt

Temporärer Kontext

Schlechtes Beispiel


oldcontext = getcontext().copy()
getcontext().prec = 50
print(Decimal(355) / Decimal(113))
setcontext(oldcontext)

Gutes Beispiel


with localcontext(Context(prec=50)):
  print(Decimal(355) / Decimal(113))

Dateien öffnen und schließen

Schlechtes Beispiel


f = open('data.txt')
try:
  data = f.read()
finally:
  f.close()

Gutes Beispiel


with open('data.txt') as f:
  data = f.read()

Gewindesperre

Schlechtes Beispiel


lock = threading.Lock()
lock.acquire()
try:
  print('Critical section 1')
  print('Critical section 2')
finally:
  lock.release()

Gutes Beispiel


lock = threading.Lock()
with lock:
  print('Critical section 1')
  print('Critical section 2')

Fehler ignorieren

Schlechtes Beispiel


try:
  os.remove('somefile.tmp')
except OSError:
  pass

Gutes Beispiel


with ignored(OSError):
  os.remove('somefile.tmp')

Standardausgabe vorübergehend ersetzen

Schlechtes Beispiel


with open('help.txt', 'w') as f:
  oldstdout = sys.stdout
  sys.stdout = f
  try:
    help(pow)
  finally:
    sys.stdout = oldstdout

Gutes Beispiel


with open('help.txt', 'w') as f:
  with redirect_stdout(f):
    help(pow)

Liste Einschlussmethode

Schlechtes Beispiel


result = []
for i in range(10):
  s = i**2
  result.append(a)
print(sum(result))

Gutes Beispiel


print(sum([i**2 for i in range(10)])

Gutes Beispiel


print(sum(i**2 for i in range(10)))

Recommended Posts

Schreiben Sie Python-ähnlichen Code
Schreiben Sie die Standardeingabe in den Code
Schreiben Sie Spigot in VS Code
Schreiben, kompilieren und führen Sie Code auf codeanywhere.com aus
Schreiben Sie Selentestcode in Python
Hinweise zum Schreiben von Python-ähnlichem Code
Schreiben Sie den Ethereum-Vertragscode mit Serpent
Qiita (1) Wie schreibe ich einen Codenamen?
Schreiben Sie testgetriebenen FizzBuzz-Code mit Python doctest.
Ist es nicht in Ordnung, Testcode zu schreiben?
Zeichencode
Schlechter Code