Nicht-idempotentes Python [geschlossen]

10

Schreiben Sie ein paar Zeilen Python-Code, der Xkeine globalen Variablen referenziert, so dass

def method():
    X
    print(a)

method()

druckt 1aber

def method():
    X
    X
    print(a)

method()

druckt 2.


Ich hasse es, ein Stickler zu sein, aber es scheint varsund localssind tatsächlich globale Variablen in Python:

def test_global_1():
    global vars, locals
    vars = lambda: 2
    locals = lambda: 3

def test_global_2():
    print(vars())
    print(locals())

test_global_1()
test_global_2()

Es sieht auch so aus, als würden die Leute gerne objektive Gewinnkriterien für solche Rätsel sehen. Die Codelänge fühlt sich hier nicht wirklich richtig an, also könnten wir vielleicht ein System von Brownie-Punkten für verschiedene neuartige Funktionen des Codes erstellen? Ich bin mir nicht sicher, was genau das sein könnte, aber hier ist ein Anfang:

  • +1 für wirklich wirklich keine Globalen (nein varsoder locals)
  • +1 für den ersten Beitrag zu einer bestimmten Technik
  • +1 für die kürzeste veröffentlichte Lösung
  • +1 für eine Lösung mit nur einer Python-Anweisung
  • +1 für interessante "Hacks" wie das Beitreten an lexikalischen Grenzen
  • +1 für die Nichtverwendung von Ausnahmen

Und wenn Ihnen mehr einfällt, können Sie diese Frage bearbeiten, um sie der Liste hinzuzufügen.

Kann dieses Problem ohne Verwendung von Ausnahmen und ohne Verwendung von Globals wie varsund gelöst werden locals? Ich vermute, es kann, obwohl ich noch nicht genau herausgefunden habe, wie ...

Owen
quelle
Gutes Puzzle! Ich habe darauf geachtet, nicht nach unten zu scrollen, damit ich es selbst lösen kann, ohne die Antworten von jemandem zu sehen. : D
mbomb007
1
Vielen Dank für die Rätsel, Owen, und willkommen auf der Website. Es gibt eine Regel auf der Website, dass alle Fragen eine objektive Gewinnbedingung haben müssen, daher sollten Sie wahrscheinlich eine hinzufügen. Eine Möglichkeit ist die kürzeste Länge X, aber es gibt andere Möglichkeiten.
isaacg
3
"Alle Fragen müssen eine objektive Gewinnbedingung haben" - Dumme Regel imho. Wer kümmert sich um einen "Gewinner", wenn wir alle das Rätsel und Lernen aus den verschiedenen Antworten am meisten genießen?
JimmyB
2
Bitte fügen Sie ein Code-Golf- oder Beliebtheitswettbewerb- Tag hinzu, je nachdem, ob die Benutzer für den Shortness-Code oder für die allgemeine Beliebtheit optimieren sollen. Ich stelle mir vor, Code-Golf ist besser für diese Herausforderung (Beliebtheitswettbewerb wird nur für Herausforderungen empfohlen, die sonst nicht einfach zu klassifizieren sind), aber es liegt an Ihnen.
Apsiller
2
Sie haben ein Punktesystem hinzugefügt, aber auch das Beliebtheitswettbewerbs-Tag hinzugefügt, was bedeutet, dass ein Gewinner durch Stimmen bestimmt wird. Was meinst du hier? Vielleicht möchten Sie Stimmen nur als Tiebreak?
xnor

Antworten:

12
def method():
    if 'a' not in vars():a=0
    a+=1
    if 'a' not in vars():a=0
    a+=1
    print(a)

Initialisiert die Variable aauf 0nur , wenn es nicht bereits in der Variablentabelle initialisiert. Dann erhöht es.

Kurz (danke an den Histokraten für len):

def method():
    a=len(vars())+1
    a=len(vars())+1
    print(a)

Wenn sich die beiden Kopien von Xin derselben Zeile befinden könnten, könnten wir dies tun

a=0;a+=1;a

was sich verdoppelt

a=0;a+=1;aa=0;a+=1;a

mit dem "Opferlamm" aa, das die zweite variable Zuordnung auffrisst.

xnor
quelle
3
Ich möchte kein Spielverderber sein, der dies so schnell veröffentlicht. Wie wäre es also, wenn wir versuchen, den kürzesten Code zu finden?
xnor
3
Etwas kürzere Variante:a=len(vars())+1
Histokrat
@histocrat Schön, danke!
xnor
9

Python

Ich dachte an diese Lösung, da tryund exceptwar der erste Weg, um festzustellen, ob eine Variable noch existiert oder nicht.

def method():
    try:a+=1
    except:a=1
    print(a)
mbomb007
quelle
5

Python 2

def method():
    exec'';locals()['a']=locals().get('a',0)+1
    exec'';locals()['a']=locals().get('a',0)+1
    print a

method()

Wenn execPython 2 angetroffen wird , wird grundsätzlich ein spezielles Flag ( 0x01) entfernt method.func_code.co_flags, wodurch localsZuweisungen wirksam werden. Ich habe dies ausgenutzt, um die nonlocalUnterstützung in Python 2 zu implementieren (siehe Zeile 43 für das xor, das das Flag ändert).

kirbyfan64sos
quelle
Warum nicht a = locals().get('a', 0) + 1?
Vincent
@ Vincent Ich war müde. : O behoben.
kirbyfan64sos
In diesem Fall brauchen Sie nicht exec''mehr;)
Vincent
@ Vincent Eh, vielleicht sollte ich mich einfach an die längere Version halten. Es fühlte sich kreativer an. Jetzt scheint es nur ein Klon der am besten
gewählten
2

Meine erste Idee (und dann das Glätten) war:

def method():
    a=2if'a'in vars()else 1 
    a=2if'a'in vars()else 1 
    print(a)

Aber die Antwort des Histokraten scheint optimal zu sein.

Don Hatch
quelle
1

Mein Versuch. Verwendet das Mathematikmodul, um zu verfolgen, ob X ein- oder zweimal ausgeführt wird.

def module():
  import sys
  if 'math' in sys.modules:
    a+=1
  else:
    a=1
  import math

  import sys
  if 'math' in sys.modules:
    a+=1
  else:
    a=1
  import math

  print(a)

module()
toto
quelle
1
def method(a=[]):  
  a.append(a)  
  print len(a)

Als Antwort auf einen Kommentar bearbeitet: a ist eine Liste leerer Listen der Länge n, wobei n die Häufigkeit ist, mit der Sie die Methode aufgerufen haben. Wenn Sie diese Methode zweimal aufrufen, wird 1 und dann 2 gedruckt.

WithScience
quelle
7
Das Setzen a=[]als Parameter liegt außerhalb der Parameter für diese Herausforderung.
mbomb007
Entschuldigung, das ist meine Antwort und es ist nicht sehr gut. Dies ist (wohl) eine überraschend nicht idempotente Operation in Python, aber es gibt keine Möglichkeit, sie in das für die Herausforderung bereitgestellte Format einzufügen, ohne die Herausforderung auch trivial zu machen.
WithScience
Die Herausforderung besteht auch darin, 1 oder 2 zu drucken, nicht nur zwei verschiedene Dinge.
xnor
0
def method():
    #### X-block
    try:a
    except NameError:a=1
    else:a=2
    ####
    print(a)

Der tryBlock prüft, ob die Variable a definiert ist.
Wenn die Variable nicht definiert ist (dies ist nur dann der NameErrorFall, wenn der X-Block einmal vorhanden ist), wird eine Ausnahme ausgelöst.
Wenn eine Variable definiert ist (dies ist der elseFall, wenn der X-Block zweimal vorhanden ist), wird er eingegeben.

Kamehameha
quelle
Ja, das ist die Lösung, die ich bei der Suche in Google gefunden habe. Dann habe ich meine aktuelle Lösung erstellt, die kürzer ist.
mbomb007
@ mbomb007 Ja: P. Ihr Weg ist kürzer als mitelse
Kamehameha