Python non idempotent [fermé]

10

Écrivez quelques lignes de code Python,, Xqui ne référencent aucune variable globale, telles que

def method():
    X
    print(a)

method()

imprime 1mais

def method():
    X
    X
    print(a)

method()

impressions 2.


Donc, je déteste être pointilleux, mais il semble que varset localssont en fait des variables globales en 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()

En outre, il semble que les gens aimeraient voir des critères de victoire objectifs pour des puzzles comme celui-ci. La longueur du code ne se sent pas vraiment ici, alors peut-être pourrions-nous créer un système de points brownie pour diverses nouvelles fonctionnalités du code? Je ne sais pas exactement ce que cela pourrait être, mais voici un début:

  • +1 pour vraiment vraiment pas de globaux (non varsou locals)
  • +1 pour avoir été le premier à publier une technique particulière
  • +1 pour la solution la plus courte publiée
  • +1 pour une solution n'impliquant qu'une seule instruction Python
  • +1 pour des "hacks" intéressants comme rejoindre des non-frontières lexicales
  • +1 pour ne pas utiliser d'exceptions

Et si vous pouvez penser à plus, vous pouvez modifier cette question pour l'ajouter à la liste.

Ce problème peut-il être résolu sans utiliser d'exceptions et sans utiliser des globaux comme varset locals? Je soupçonne que c'est possible, même si je n'ai pas encore compris exactement comment ...

Owen
la source
Bon puzzle! Je me suis assuré de ne pas faire défiler vers le bas afin de pouvoir le résoudre moi-même sans voir les réponses de personne. : D
mbomb007
1
Merci pour les puzzles Owen, et bienvenue sur le site. Il existe une règle sur le site selon laquelle toutes les questions doivent avoir une condition de gain objective, vous devez donc probablement en ajouter une. Une possibilité est la longueur la plus courte X, mais il existe d'autres options.
isaacg
3
"toutes les questions doivent avoir une condition de victoire objective" - ​​stupide règle à mon humble avis. Qui se soucie d'un «gagnant» alors que nous apprécions tous le plus le déroutement et l'apprentissage des différentes réponses.
JimmyB
2
Veuillez ajouter un code-golf ou un tag de concours de popularité , selon que vous souhaitez que les gens optimisent le code de raccourci ou la popularité générale. J'imagine que le code-golf est meilleur pour ce défi (le concours de popularité n'est encouragé que pour les défis qui ne peuvent pas être facilement classés autrement), mais c'est à vous.
apsillers
2
Vous avez ajouté un système de notation, mais vous avez également ajouté la balise du concours de popularité, ce qui signifie qu'un gagnant est décidé par des votes. Que voulez-vous dire ici? Peut-être que vous voulez des votes comme bris d'égalité?
xnor

Réponses:

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

Initialise la variable aà 0seulement si elle est pas déjà initialisé dans le tableau des variables. Ensuite, l'incrémente.

Plus brièvement (merci à l'histocrate pour len):

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

Si les deux copies de Xpouvaient être sur la même ligne, nous pourrions faire

a=0;a+=1;a

qui double à

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

avec "l'agneau sacrificiel" aadévorant la deuxième affectation variable.

xnor
la source
3
Je ne veux pas être un spoilsport en publiant si vite, alors pourquoi ne pas essayer le code le plus court?
2015 à 20h03
3
Variante légèrement plus courte:a=len(vars())+1
histocrate
@histocrat Nice one, thanks!
2015
9

Python

La pensée de cette solution, car tryet excepta été la première façon dont je pensais de déterminer si une variable existe encore ou non.

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

Python 2

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

method()

Fondamentalement, lorsqu'il execest rencontré dans Python 2, il provoque la 0x01suppression d' un indicateur spécial ( ) method.func_code.co_flags, ce qui fait que les localsaffectations ont un effet. J'ai exploité cela pour implémenter le nonlocalsupport en Python 2 (voir la ligne 43 pour le xor qui modifie le drapeau).

kirbyfan64sos
la source
Pourquoi pas a = locals().get('a', 0) + 1?
Vincent
@Vincent j'étais fatigué. : O Fixe.
kirbyfan64sos
Dans ce cas, vous n'en avez plus besoin exec'';)
Vincent
@Vincent Eh, je devrais peut-être simplement m'en tenir à la version plus longue. C'était plus créatif. Maintenant, cela ressemble beaucoup à un clone de la réponse la plus votée ...: /
kirbyfan64sos
2

Ma première idée (puis la faire naître) a été:

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

Mais la réponse de l'histocrate semble optimale.

Don Hatch
la source
1

Ma tentative. Utilise le module mathématique pour suivre si X est exécuté une ou deux fois.

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
la source
1
def method(a=[]):  
  a.append(a)  
  print len(a)

Modifié en réponse au commentaire: a est une liste de listes vides de longueur n, où n est le nombre de fois que vous avez appelé la méthode. L'appel de cette méthode imprime deux fois 1 puis 2.

WithScience
la source
7
La mise a=[]en paramètre est en dehors des paramètres de ce défi.
mbomb007
Désolé, c'est ma réponse, et ce n'est pas très bon. Il s'agit (sans doute) d'une opération étonnamment non idempotente en python, mais il n'y a aucun moyen de le placer dans le format fourni pour le défi sans également rendre le défi trivial.
WithScience
De plus, le défi consiste à imprimer 1 ou 2, et pas seulement deux choses différentes.
xnor
0
def method():
    #### X-block
    try:a
    except NameError:a=1
    else:a=2
    ####
    print(a)

Le trybloc vérifie si la variable a est définie.
Si la variable n'est pas définie (c'est uniquement lorsque le bloc X est présent une fois), une NameErrorexception est déclenchée.
Si une variable est définie, (c'est lorsque le bloc X est présent deux fois), alors elsesera entré.

Kamehameha
la source
Oui, c'est la solution que j'ai trouvée en recherchant Google. J'ai ensuite créé ma solution actuelle, qui est plus courte.
mbomb007
@ mbomb007 Ouais: P. Votre chemin est plus court que l'utilisationelse
Kamehameha