Python không bình thường [đã đóng]


10

Viết một vài dòng mã Python, Xkhông tham chiếu bất kỳ biến toàn cục nào, sao cho

def method():
    X
    print(a)

method()

in 1nhưng

def method():
    X
    X
    print(a)

method()

bản in 2.


Vì vậy, tôi ghét trở thành một stickler, nhưng có vẻ như varslocalsthực sự là các biến toàn cục trong 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()

Ngoài ra, có vẻ như mọi người muốn thấy các tiêu chí chiến thắng khách quan cho các câu đố như thế này. Độ dài mã không thực sự cảm thấy ngay tại đây vì vậy có lẽ chúng ta có thể tạo ra một hệ thống các điểm brownie cho các tính năng mới lạ khác nhau của mã? Tôi không chắc chính xác những gì có thể nhưng đây là một sự khởi đầu:

  • +1 cho thực sự thực sự không có toàn cầu (không varshoặc locals)
  • +1 vì là người đầu tiên đăng một kỹ thuật cụ thể
  • +1 cho giải pháp ngắn nhất được đăng
  • +1 cho một giải pháp chỉ liên quan đến một câu lệnh Python
  • +1 cho các "hack" thú vị như tham gia ở các ranh giới từ vựng
  • +1 không sử dụng ngoại lệ

Và nếu bạn có thể nghĩ nhiều hơn, bạn có thể chỉnh sửa câu hỏi này để thêm vào danh sách.

Vấn đề này có thể được giải quyết mà không cần sử dụng ngoại lệ không sử dụng toàn cầu như varslocalskhông? Tôi nghi ngờ điều đó có thể, mặc dù tôi vẫn chưa biết chính xác ...


Câu đố hay! Tôi đảm bảo không cuộn xuống để tôi có thể tự giải quyết mà không cần xem câu trả lời của bất kỳ ai. : D
mbomb007

1
Cảm ơn các câu đố Owen, và chào mừng đến với trang web. Có một quy tắc trên trang web là tất cả các câu hỏi phải có một điều kiện chiến thắng khách quan, vì vậy bạn có thể nên thêm một câu hỏi. Một khả năng là chiều dài ngắn nhất X, nhưng có những lựa chọn khác.
isaacg

3
"tất cả các câu hỏi phải có một điều kiện chiến thắng khách quan" - Quy tắc ngu ngốc imho. Ai quan tâm đến một "người chiến thắng" khi tất cả chúng ta thực sự thích thú với sự khó hiểu và học hỏi từ các câu trả lời khác nhau.
JimmyB

2
Vui lòng thêm thẻ mã golf hoặc cuộc thi phổ biến , tùy thuộc vào việc bạn muốn mọi người tối ưu hóa cho mã ngắn hay phổ biến chung. Tôi tưởng tượng code-golf tốt hơn cho thử thách này (cuộc thi phổ biến chỉ được khuyến khích cho những thử thách không thể dễ dàng phân loại khác), nhưng điều đó tùy thuộc vào bạn.
apsillers

2
Bạn đã thêm một hệ thống tính điểm, nhưng cũng đã thêm thẻ cuộc thi phổ biến, điều đó có nghĩa là người chiến thắng được quyết định bằng phiếu bầu. Bạn có ý nghĩa gì ở đây? Có lẽ bạn muốn phiếu bầu chỉ là một tiebreak?
xnor

Câu trả lời:


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

Khởi tạo biến athành 0chỉ khi nó chưa được khởi tạo trong bảng biến. Sau đó, tăng nó.

Ngắn gọn hơn (cảm ơn lịch sử cho len):

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

Nếu hai bản sao Xcó thể nằm trên cùng một dòng, chúng ta có thể làm

a=0;a+=1;a

nhân đôi

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

với "con chiên hiến tế" aaăn hết nhiệm vụ biến thứ hai.


3
Tôi không muốn trở thành một spoilsport đăng bài này quá nhanh, vậy chúng ta thử mã ngắn nhất thì sao?
xnor

3
Biến thể ngắn hơn một chút:a=len(vars())+1
lịch sử

@histocrat Đẹp một cái, cảm ơn!
xnor

9

Con trăn

Nghĩ đến giải pháp này, vì tryexceptlà cách đầu tiên tôi nghĩ đến để xác định xem một biến có tồn tại hay không.

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

5

Con trăn 2

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

method()

Về cơ bản, khi execgặp phải trong Python 2, nó làm cho một cờ đặc biệt ( 0x01) bị xóa khỏi method.func_code.co_flags, điều này làm cho các localsbài tập có hiệu lực. Tôi đã khai thác điều này để triển khai nonlocalhỗ trợ trong Python 2 (xem dòng 43 cho xor sửa đổi cờ).


Tại sao không a = locals().get('a', 0) + 1?
Vincent

@Vincent Tôi đã tiree. : O Đã sửa.
kirbyfan64sos

Trong trường hợp đó, bạn không cần exec''thêm nữa;)
Vincent

@Vincent Eh, có lẽ tôi chỉ nên gắn bó với phiên bản dài hơn. Nó cảm thấy sáng tạo hơn. Bây giờ nó có vẻ giống như một bản sao của câu trả lời được bình chọn hàng đầu ...: /
kirbyfan64sos

2

Ý tưởng đầu tiên của tôi (và sau đó smooshing nó) là:

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

Nhưng câu trả lời của histocrat có vẻ tối ưu.


1

Nỗ lực của tôi. Sử dụng mô-đun toán học để theo dõi nếu X được chạy một hoặc hai lần.

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)

Đã chỉnh sửa để phản hồi nhận xét: a là danh sách các danh sách trống có độ dài n, trong đó n là số thời gian bạn gọi là phương thức. Gọi phương thức này hai lần in 1 rồi 2.


7
Đặt a=[]làm tham số nằm ngoài các tham số cho thử thách này.
mbomb007

Xin lỗi, đây là câu trả lời của tôi, và nó không hay lắm. Đây có thể là một hoạt động phi bình thường đáng kinh ngạc ở python, nhưng không có cách nào để đưa nó vào định dạng được cung cấp cho thử thách mà không làm cho thách thức trở nên tầm thường.
WithScience

Ngoài ra, thử thách yêu cầu in 1 hoặc 2, không chỉ hai điều khác nhau.
xnor

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

Các trykiểm tra khối nếu một biến được định nghĩa.
Nếu biến không được xác định, (đây chỉ là khi khối X xuất hiện một lần) thì NameErrorNgoại lệ được nâng lên.
Nếu biến được xác định, (đây là khi khối X xuất hiện hai lần) thì elsesẽ được nhập.


Vâng, đó là giải pháp tôi tìm thấy bằng cách tìm kiếm Google. Sau đó, tôi tạo ra giải pháp hiện tại của tôi, đó là ngắn hơn.
mbomb007

@ mbomb007 Vâng: P. Cách của bạn ngắn hơn so với sử dụngelse
Kamehameha
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.