Python Non-idempoten [ditutup]

10

Tulis beberapa baris kode Python X,, yang tidak merujuk variabel global apa pun, seperti itu

def method():
    X
    print(a)

method()

mencetak 1tetapi

def method():
    X
    X
    print(a)

method()

cetakan 2.


Jadi, saya benci menjadi ngotot, tetapi sepertinya varsdan localssebenarnya adalah variabel global dalam 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()

Juga, sepertinya orang ingin melihat kriteria kemenangan yang objektif untuk teka-teki seperti ini. Panjang kode tidak terasa di sini, jadi mungkin kita bisa membuat sistem poin brownies untuk berbagai fitur baru kode? Saya tidak yakin persis apa ini tetapi di sinilah awalnya:

  • +1 untuk benar-benar tanpa global (tidak varsatau locals)
  • +1 karena menjadi orang pertama yang memposting teknik tertentu
  • +1 untuk solusi terpendek yang diposting
  • +1 untuk solusi yang hanya melibatkan satu pernyataan Python
  • +1 untuk "retasan" yang menarik seperti bergabung di lexical non-boundaries
  • +1 karena tidak menggunakan pengecualian

Dan jika Anda dapat memikirkan lebih lanjut, Anda dapat mengedit pertanyaan ini untuk ditambahkan ke daftar.

Bisakah masalah ini diselesaikan tanpa menggunakan pengecualian dan tanpa menggunakan global seperti varsdan locals? Saya menduga itu bisa, meskipun saya belum tahu persis bagaimana ...

Owen
sumber
Teka-teki yang bagus! Saya memastikan untuk tidak menggulir ke bawah sehingga saya bisa menyelesaikannya sendiri tanpa melihat jawaban siapa pun. : D
mbomb007
1
Terima kasih untuk teka-teki Owen, dan selamat datang di situs. Ada aturan di situs bahwa semua pertanyaan harus memiliki kondisi kemenangan yang objektif, jadi Anda mungkin harus menambahkannya. Satu kemungkinan adalah yang terpendek X, tetapi ada opsi lain.
isaacg
3
"semua pertanyaan harus memiliki kondisi kemenangan yang objektif" - Aturan bodoh. Siapa yang peduli dengan "pemenang" ketika kita semua benar-benar menikmati kebingungan dan belajar dari jawaban yang berbeda.
JimmyB
2
Harap tambahkan tag kode-golf atau popularitas-kontes , tergantung pada apakah Anda ingin orang mengoptimalkan kode pendek atau untuk popularitas umum. Saya membayangkan kode-golf lebih baik untuk tantangan ini (kontes popularitas didorong hanya untuk tantangan yang tidak dapat dengan mudah diklasifikasikan sebaliknya), tetapi terserah Anda.
apsillers
2
Anda telah menambahkan sistem penilaian, tetapi juga menambahkan tag kontes popularitas, yang berarti bahwa pemenang ditentukan oleh suara. Apa maksudmu disini? Mungkin Anda ingin suara hanya sebagai tiebreak?
xnor

Jawaban:

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

Menginisialisasi variabel auntuk 0hanya jika itu belum diinisialisasi dalam tabel variabel. Lalu, tambahkan itu.

Lebih singkat (terima kasih kepada histokrat untuk len):

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

Jika dua salinan Xdapat berada di baris yang sama, kita bisa melakukannya

a=0;a+=1;a

yang berlipat ganda menjadi

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

dengan "domba kurban" aamemakan tugas variabel kedua.

Tidak
sumber
3
Saya tidak ingin menjadi spoilsport memposting ini begitu cepat, jadi bagaimana kalau kita mencoba kode terpendek?
xnor
3
Varian sedikit lebih pendek:a=len(vars())+1
histokrat
@ histokrat Bagus, terima kasih!
xnor
9

Python

Memikirkan solusi ini, karena trydan exceptmerupakan cara pertama yang saya pikirkan untuk menentukan apakah suatu variabel sudah ada atau belum.

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

Python 2

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

method()

Pada dasarnya, ketika execditemui dalam Python 2, itu menyebabkan flag ( 0x01) khusus untuk dihapus method.func_code.co_flags, yang membuat localstugas memiliki efek. Saya mengeksploitasi ini untuk mengimplementasikan nonlocaldukungan dalam Python 2 (lihat baris 43 untuk xor yang memodifikasi flag).

kirbyfan64sos
sumber
Mengapa tidak a = locals().get('a', 0) + 1?
Vincent
@Vincent aku tiree. : O Diperbaiki.
kirbyfan64sos
Dalam hal ini Anda tidak perlu exec''lagi;)
Vincent
@Incent Eh, mungkin saya harus tetap dengan versi yang lebih panjang. Rasanya lebih kreatif. Sekarang sepertinya sangat mirip klon dari jawaban terpilih ...: /
kirbyfan64sos
2

Gagasan pertama saya (dan kemudian mengonsumsinya) adalah:

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

Tetapi jawaban histokrat tampaknya optimal.

Don Hatch
sumber
1

Usaha saya. Menggunakan modul matematika untuk melacak jika X dijalankan sekali atau dua kali.

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

Diedit dalam menanggapi komentar: a adalah daftar daftar panjang kosong n, di mana n adalah jumlah waktu yang Anda panggil metode. Memanggil metode ini dua kali mencetak 1 kemudian 2.

WithScience
sumber
7
Puting a=[]sebagai parameter berada di luar parameter untuk tantangan ini.
mbomb007
Maaf, ini jawaban saya, dan itu tidak terlalu baik. Ini (bisa dibilang) adalah operasi non-idempoten yang mengejutkan, tetapi tidak ada cara untuk memasukkannya ke dalam format yang disediakan untuk tantangan tanpa juga membuat tantangan sepele.
WithScience
Juga, tantangannya meminta untuk mencetak 1 atau 2, bukan hanya dua hal yang berbeda.
xnor
0
def method():
    #### X-block
    try:a
    except NameError:a=1
    else:a=2
    ####
    print(a)

The trycek blok jika variabel didefinisikan.
Jika variabel tidak didefinisikan, (ini hanya ketika X-blok hadir sekali) maka NameErrorPengecualian dinaikkan.
Jika variabel didefinisikan, (ini adalah ketika X-blok hadir dua kali) maka elseakan dimasukkan.

Kamehameha
sumber
Ya, itulah solusi yang saya temukan dengan mencari di Google. Kemudian saya membuat solusi saya saat ini, yang lebih pendek.
mbomb007
@ mbomb007 Ya: P. Cara Anda lebih pendek daripada menggunakanelse
Kamehameha