Python ที่ไม่ใช่ idempotent [ปิด]


10

เขียนโค้ด Python สองสามบรรทัดXซึ่งไม่ได้อ้างอิงตัวแปรโกลบอลใด ๆ เช่นนั้น

def method():
    X
    print(a)

method()

พิมพ์1แต่

def method():
    X
    X
    print(a)

method()

2พิมพ์


ดังนั้นฉันเกลียดที่จะเป็น stickler แต่ดูเหมือนว่าvarsและlocalsเป็นตัวแปรทั่วโลกใน 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()

นอกจากนี้ดูเหมือนว่าผู้คนต้องการเห็นเกณฑ์การชนะอย่างมีวัตถุประสงค์สำหรับปริศนาเช่นนี้ ความยาวของรหัสไม่ได้ให้ความรู้สึกที่นี่ดังนั้นบางทีเราอาจสร้างระบบของจุดบราวนี่สำหรับคุณสมบัติใหม่ ๆ ฉันไม่แน่ใจว่าสิ่งเหล่านี้อาจเป็นอะไร แต่นี่เป็นการเริ่มต้น:

  • +1 สำหรับ globals จริง ๆ อย่างแท้จริง (ไม่varsหรือlocals)
  • +1 สำหรับการเป็นคนแรกที่โพสต์เทคนิคเฉพาะ
  • +1 สำหรับโซลูชันที่สั้นที่สุดที่โพสต์
  • +1 สำหรับการแก้ปัญหาที่เกี่ยวข้องกับคำสั่ง Python เพียงคำเดียว
  • +1 สำหรับ "แฮ็ก" ที่น่าสนใจเช่นเข้าร่วมที่ศัพท์ที่ไม่ใช่ขอบเขต
  • +1 สำหรับการไม่ใช้ข้อยกเว้น

และถ้าคุณคิดมากกว่านี้คุณสามารถแก้ไขคำถามนี้เพื่อเพิ่มลงในรายการ

สามารถแก้ไขปัญหานี้ได้โดยไม่ใช้ข้อยกเว้นและไม่ใช้ globals เช่นvarsและlocals? ฉันสงสัยว่ามันสามารถทำได้ถึงแม้ว่าฉันจะไม่ได้คิดออกยังไงว่า ...


ปริศนาดี! ฉันแน่ใจว่าจะไม่เลื่อนลงเพื่อให้ฉันสามารถแก้ไขได้ด้วยตัวเองโดยไม่เห็นคำตอบของใคร : D
mbomb007

1
ขอบคุณสำหรับปริศนา Owen และยินดีต้อนรับสู่เว็บไซต์ มีกฎในเว็บไซต์ที่คำถามทุกข้อจะต้องมีเงื่อนไขการชนะวัตถุประสงค์ดังนั้นคุณอาจจะต้องเพิ่มหนึ่ง ความเป็นไปได้อย่างหนึ่งคือความยาวสั้นที่สุดXแต่ก็มีตัวเลือกอื่น
isaacg

3
"คำถามทั้งหมดจะต้องมีเงื่อนไขการชนะอย่างมีเป้าหมาย" - กฎโง่ ๆ ใครสนใจเกี่ยวกับ "ผู้ชนะ" เมื่อเราทุกคนสนุกกับการงงและเรียนรู้จากคำตอบที่แตกต่างกัน
JimmyB

2
โปรดเพิ่มรหัส-golfหรือแท็กการประกวดความนิยมขึ้นอยู่กับว่าคุณต้องการให้คนเพิ่มประสิทธิภาพสำหรับรหัสย่อหรือเพื่อความนิยมทั่วไป ฉันคิดว่า code-golf ดีกว่าสำหรับความท้าทายนี้ (การประกวดความนิยมได้รับการสนับสนุนสำหรับความท้าทายที่ไม่สามารถจำแนกได้ง่าย ๆ ) แต่ขึ้นอยู่กับคุณ
apsillers

2
คุณได้เพิ่มระบบการให้คะแนน แต่ยังเพิ่มแท็กการประกวดความนิยมซึ่งหมายความว่าผู้ชนะจะตัดสินด้วยคะแนนโหวต คุณหมายถึงอะไรที่นี่ บางทีคุณอาจต้องการคะแนนเสียงเช่นเดียวกับการเบรค?
xnor

คำตอบ:


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

เริ่มต้นตัวแปรaไป0เท่านั้นหากยังไม่ได้เริ่มต้นแล้วในตารางตัวแปร จากนั้นเพิ่มขึ้น

เพิ่มเติมสั้น ๆ (ขอบคุณสำหรับนักประวัติศาสตร์เพื่อlen):

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

หากทั้งสองสำเนาXสามารถอยู่ในบรรทัดเดียวกันเราก็ทำได้

a=0;a+=1;a

ซึ่งเพิ่มเป็นสองเท่า

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

กับ "แกะบูชายัญ" aaกินการมอบหมายตัวแปรที่สอง


3
ฉันไม่ต้องการที่จะเป็นผู้ส่งข้อความด่วนอย่างรวดเร็วดังนั้นเราลองใช้รหัสที่สั้นที่สุดได้อย่างไร
xnor

3
ตัวแปรที่สั้นกว่าเล็กน้อย:a=len(vars())+1
ฮิสโทแคต

@ ขุนนางผู้มีความสุขขอบคุณ!
xnor

9

หลาม

ความคิดของการแก้ปัญหานี้ตั้งแต่tryและexceptเป็นวิธีแรกที่ฉันคิดว่าจะตรวจสอบว่าตัวแปรที่มีอยู่หรือยัง

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

โดยทั่วไปเมื่อexecพบใน Python 2 จะทำให้การลบการตั้งค่าสถานะพิเศษ ( 0x01) จากmethod.func_code.co_flagsซึ่งทำให้การlocalsกำหนดมีผล ฉันใช้ประโยชน์จากสิ่งนี้เพื่อดำเนินการnonlocalสนับสนุนใน Python 2 (ดูบรรทัดที่ 43 สำหรับ xor ที่ปรับเปลี่ยนค่าสถานะ)


ทำไมไม่a = locals().get('a', 0) + 1?
วินเซนต์

@ เร็ว ๆ นี้ฉันเป็นคนดี : O คงที่
kirbyfan64sos

ในกรณีนี้คุณไม่ต้องการexec''อีกต่อไป;)
Vincent

@Vincent Eh บางทีฉันควรจะติดกับรุ่นที่ยาวกว่า มันรู้สึกสร้างสรรค์มากขึ้น ตอนนี้ดูเหมือนว่าจะเป็นเหมือนคำตอบที่ได้รับการโหวตมากที่สุด ... : /
kirbyfan64sos

2

ความคิดแรกของฉัน (และจากนั้น smooshing มัน) คือ:

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

แต่คำตอบของฮิสโทแคตดูเหมือนดีที่สุด


1

ความพยายามของฉัน ใช้โมดูลคณิตศาสตร์เพื่อติดตามว่า X รันครั้งเดียวหรือสองครั้ง

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)

แก้ไขเพื่อตอบสนองต่อความคิดเห็น: a คือรายการของรายการความยาวที่ว่างเปล่า n โดยที่ n คือจำนวนเวลาที่คุณเรียกว่าเมธอด การเรียกใช้วิธีนี้สองครั้งพิมพ์ 1 แล้ว 2


7
การวางa=[]เป็นพารามิเตอร์อยู่นอกพารามิเตอร์สำหรับการท้าทายนี้
mbomb007

ขออภัยนี่คือคำตอบของฉันและมันก็ไม่ค่อยดี นี่คือการดำเนินการที่ไม่น่าแปลกใจในภาษาไพ ธ อน แต่ไม่มีวิธีใดที่จะนำไปวางในรูปแบบที่จัดไว้ให้สำหรับความท้าทายโดยไม่ต้องทำการท้าทายเล็กน้อย
WithScience

ความท้าทายขอให้พิมพ์ 1 หรือ 2 ไม่ใช่แค่สองอย่างที่แตกต่างกัน
xnor

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

tryตรวจสอบบล็อกถ้าตัวแปรที่ถูกกำหนด
หากไม่ได้กำหนดตัวแปรไว้ (นี่เป็นเพียงเมื่อมี X-block อยู่ครั้งเดียว) ดังนั้นNameErrorจะมีการยกข้อยกเว้นขึ้น
หากมีการกำหนดตัวแปร (นี่คือเมื่อ X-block มีอยู่สองครั้ง) จากนั้นelseจะถูกป้อน


ใช่นั่นคือคำตอบที่ฉันค้นพบจากการค้นหา Google จากนั้นฉันสร้างโซลูชันปัจจุบันซึ่งสั้นกว่า
mbomb007

@ mbomb007 ใช่: P วิธีของคุณสั้นกว่าการใช้else
Kamehameha
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.