İdempotent olmayan Python [kapalı]


10

XKüresel değişkenlere referans vermeyen birkaç satır Python kodu yazın , öyle ki

def method():
    X
    print(a)

method()

yazdırıyor 1ama

def method():
    X
    X
    print(a)

method()

yazdırır 2.


Yani, bir stickler olmaktan nefret ediyorum, ama aslında Python'daki küresel değişkenler gibi görünüyor varsve locals:

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

Ayrıca, insanlar bunun gibi bulmacalar için objektif kazanma kriterleri görmek istiyor gibi görünüyor. Kod uzunluğu gerçekten burada hissetmiyor, bu yüzden belki de kodun çeşitli yeni özellikleri için bir brownie noktaları sistemi yapabiliriz? Bunların ne olabileceğinden tam olarak emin değilim ama işte bir başlangıç:

  • Gerçekten küresel olmayanlar için +1 (hayır varsveya locals)
  • Belirli bir tekniği ilk yayınlayan kişi olarak +1
  • Gönderilen en kısa çözüm için +1
  • Tek bir Python deyimi içeren bir çözüm için +1
  • Sözcüksel sınırlar dışında katılmak gibi ilginç "kesmek" için +1
  • İstisnaları kullanmadığınız için +1

Ve daha fazlasını düşünebiliyorsanız, listeye eklemek için bu soruyu düzenleyebilirsiniz.

Bu sorun istisnaları kullanmadan çözülebilir ve benzeri globalsi kullanmadan varsve locals? Bunun tam olarak nasıl olduğunu henüz çözememiş olmama rağmen şüphelenebiliyorum ...


İyi bulmaca! Kimsenin cevaplarını görmeden kendim çözebilmem için aşağı kaydırmamaya dikkat ettim. : D
mbomb007

1
Owen bulmaca için teşekkürler ve siteye hoş geldiniz. Sitede tüm soruların nesnel bir kazanma koşulu olması gerektiğine dair bir kural vardır, bu yüzden muhtemelen bir tane eklemelisiniz. Bir olasılık en kısa uzunluğudur X, ancak başka seçenekler de vardır.
isaacg

3
"tüm sorular objektif bir kazanma koşulu olmalıdır" - Aptal kural imho. Hepimiz en çok farklı cevaplardan şaşkınlık ve öğrenme zevk zaman bir "kazanan" umurunda.
JimmyB

2
Lütfen insanların kısayol kodu veya genel popülerlik için optimizasyon yapmasını isteyip istemediğinize bağlı olarak bir kod golf veya popülerlik yarışması etiketi ekleyin . Ben kod-golf bu meydan okuma için daha iyi olduğunu düşünüyorum (popülerlik-yarışması sadece kolayca sınıflandırılamaz zorluklar için teşvik edilir), ama size kalmış.
apsillers

2
Bir puanlama sistemi eklediniz, ancak popülerlik yarışması etiketini de eklediniz, bu da bir kazananın oylarla kararlaştırıldığı anlamına geliyor. Burada ne demek istiyorsun? Belki de oyunuzu bir tiebreak olarak mı istiyorsunuz?
xnor

Yanıtlar:


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

Değişkeni başlatır aiçin 0zaten değişkenleri tabloda başlatıldı değil yalnızca. Sonra onu artırır.

Daha kısaca (için histokrat sayesinde len):

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

Eğer iki kopyası Xaynı satırda olabilirse,

a=0;a+=1;a

hangisi ikiye katlanır

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

"kurban kuzu" aaikinci değişken ödevi yiyor.


3
Bunu bu kadar hızlı gönderen bir spoilsport olmak istemiyorum, bu yüzden en kısa kodu denemeye ne dersin?
xnor

3
Biraz daha kısa değişken:a=len(vars())+1
histokrat

@histocrat Güzel biri, teşekkürler!
xnor

9

piton

Bu çözümün düşüncesi, o zamandan beri tryve exceptbir değişkenin henüz var olup olmadığını belirlemenin ilk yolu oldu.

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

Temel olarak, execPython 2'de karşılaşıldığında, özel bir işaretin ( 0x01) kaldırılmasına neden olur method.func_code.co_flags, bu da localsatamaların bir etkiye sahip olmasını sağlar . Bunu nonlocalPython 2'de destek uygulamak için kullandım (bayrağı değiştiren xor için 43. satıra bakınız).


Neden olmasın a = locals().get('a', 0) + 1?
Vincent

@Vincent yoruldum. : O Sabit.
kirbyfan64sos

Bu durumda artık ihtiyacınız yok exec'';)
Vincent

@Vincent Eh, belki sadece daha uzun versiyona sadık kalmalıyım. Daha yaratıcı hissetti. Şimdi sadece en çok oy alan cevabın bir klonu gibi görünüyor ...: /
kirbyfan64sos

2

İlk fikrim (ve daha sonra smooshing):

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

Ancak histokratın cevabı optimal görünüyor.


1

Denemem. X'in bir veya iki kez çalıştırılıp çalıştırılmadığını izlemek için matematik modülünü kullanır.

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)

Yoruma yanıt olarak düzenlendi: a boş n listelerinin listesidir, burada n yöntem çağırdığınız süredir. Bu yöntemin iki kez çağrılması önce 1 sonra 2'yi yazdırır.


7
a=[]Parametre olarak koymak , bu zorluğun parametrelerinin dışındadır.
mbomb007

Üzgünüm, bu benim cevabım ve çok iyi değil. Bu (tartışmalı olarak) python'da şaşırtıcı derecede idempotent olmayan bir işlemdir, ancak meydan okumayı önemsiz hale getirmeden meydan okuma için sağlanan formata yerleştirmenin bir yolu yoktur.
WithScience

Ayrıca, zorluk sadece iki farklı şeyi değil, 1 veya 2'yi yazdırmayı ister.
xnor

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

tryBlok kontrol değişkeni tanımlanmış ise.
Değişken tanımlanmamışsa (bu yalnızca X bloğu bir kez bulunduğunda geçerlidir) NameErrorİstisna ortaya çıkar.
Değişken tanımlanmışsa (bu X bloğunun iki kez mevcut olduğu zamandır) elsegirilecektir.


Evet, Google'da arama yaparak bulduğum çözüm bu. Sonra daha kısa olan mevcut çözümümü yarattım.
mbomb007

@ mbomb007 Evet: S. else
Kamehameha
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.