Python non idempotente [chiuso]


10

Scrivi alcune righe di codice Python X, che non fa riferimento a nessuna variabile globale, tale che

def method():
    X
    print(a)

method()

stampe 1ma

def method():
    X
    X
    print(a)

method()

stampe 2.


Quindi, odio essere un pignolo, ma sembra varse in localsrealtà sono variabili globali 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()

Inoltre, sembra che le persone vorrebbero vedere criteri vincenti oggettivi per puzzle come questo. La lunghezza del codice non si sente proprio qui, quindi forse potremmo creare un sistema di punti brownie per varie nuove funzionalità del codice? Non sono sicuro di cosa potrebbero essere questi ma ecco un inizio:

  • +1 per davvero davvero senza globali (no varso locals)
  • +1 per essere il primo a pubblicare una tecnica particolare
  • +1 per la soluzione più breve pubblicata
  • +1 per una soluzione che coinvolge solo una singola istruzione Python
  • +1 per "hack" interessanti come unirsi a confini non lessicali
  • +1 per non usare eccezioni

E se riesci a pensare ad altro, puoi modificare questa domanda da aggiungere all'elenco.

Questo problema può essere risolto senza usare eccezioni e senza usare globi come varse locals? Sospetto che possa, anche se non ho ancora capito esattamente come ...


Buon puzzle! Mi sono assicurato di non scorrere verso il basso in modo da poterlo risolvere da solo senza vedere le risposte di nessuno. : D
mbomb007,

1
Grazie per i puzzle Owen e benvenuti nel sito. Esiste una regola sul sito secondo cui tutte le domande devono avere una condizione vincente obiettiva, quindi dovresti probabilmente aggiungerne una. Una possibilità è la lunghezza più breve di X, ma ci sono altre opzioni.
Isaacg,

3
"tutte le domande devono avere una condizione oggettiva vincente" - Imho stupido. Chi se ne frega di un "vincitore" quando in realtà tutti noi apprezziamo molto il puzzle e l'apprendimento dalle diverse risposte.
JimmyB,

2
Aggiungi un tag code-golf o contest di popolarità , a seconda che tu voglia ottimizzare le persone per il codice shortness o per la popolarità generale. Immagino che il code-golf sia migliore per questa sfida (il concorso di popolarità è incoraggiato solo per sfide che non possono essere facilmente classificate altrimenti), ma dipende da te.
apsillers

2
Hai aggiunto un sistema di punteggio, ma hai anche aggiunto il tag del concorso di popolarità, il che significa che un vincitore viene deciso dai voti. Cosa intendi qui? Forse vuoi i voti solo come un tiebreak?
xnor

Risposte:


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

Inizializza la variabile aal 0solo se non è già inizializzato nella tabella delle variabili. Quindi, lo incrementa.

Più brevemente (grazie a Histocrat per len):

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

Se le due copie di Xpotessero essere sulla stessa linea, potremmo farlo

a=0;a+=1;a

che raddoppia a

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

con l '"agnello sacrificale" che aaconsuma il secondo compito variabile.


3
Non voglio essere uno spoiler a pubblicare questo post così in fretta, quindi che ne dite di cercare il codice più breve?
xnor

3
Variante leggermente più corta:a=len(vars())+1
istocratico

@histocrat Bello, grazie!
xnor

9

Pitone

Pensato a questa soluzione, poiché tryed è exceptstato il primo modo in cui ho pensato di determinare se esistesse o meno una variabile.

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

5

Python 2

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

method()

Fondamentalmente, quando execviene rilevato in Python 2, 0x01viene rimosso un flag speciale ( ) method.func_code.co_flags, il che fa sì che le localsassegnazioni abbiano effetto. L'ho sfruttato per implementare il nonlocalsupporto in Python 2 (vedere la riga 43 per lo xor che modifica il flag).


Perché no a = locals().get('a', 0) + 1?
Vincent,

@ Vincent ero stanco. : O fisso.
kirbyfan64sos

In tal caso non ti serve exec''più;)
Vincent

@ Vincent Eh, forse dovrei semplicemente attenermi alla versione più lunga. Sembrava più creativo. Ora sembra proprio un clone della risposta più votata ...: /
kirbyfan64sos

2

La mia prima idea (e poi la smooshing) è stata:

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

Ma la risposta dell'istocrate sembra ottimale.


1

Il mio tentativo Utilizza il modulo matematico per tracciare se X viene eseguito una o due volte.

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

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

Modificato in risposta al commento: a è un elenco di elenchi vuoti di lunghezza n, dove n è il numero di volte in cui hai chiamato il metodo. Chiamare questo metodo due volte stampa 1 poi 2.


7
Mettere a=[]come parametro è al di fuori dei parametri per questa sfida.
mbomb007,

Scusa, questa è la mia risposta e non è molto buona. Questa è (senza dubbio) un'operazione sorprendentemente non idempotente in Python, ma non c'è modo di inserirla nel formato fornito per la sfida senza renderla banale.
WithScience,

Inoltre, la sfida richiede di stampare 1 o 2, non solo due cose diverse.
xnor

0
def method():
    #### X-block
    try:a
    except NameError:a=1
    else:a=2
    ####
    print(a)

Il tryblocco verifica se la variabile a è definita.
Se la variabile non è definita, (questo è solo quando X-block è presente una volta), NameErrorviene generata l'eccezione.
Se la variabile è definita, (questo è quando il blocco X è presente due volte), allora elseverrà inserito.


Sì, questa è la soluzione che ho trovato cercando su Google. Quindi ho creato la mia soluzione attuale, che è più breve.
mbomb007,

@ mbomb007 Sì: P. La tua strada è più breve dell'usoelse
Kamehameha,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.