杰瑞科技汇

Python中如何实现高尔夫编程?

Of course! "Golfing" in Python refers to the practice of writing code in the most concise way possible, character by character. It's a fun and challenging puzzle-like activity that often requires deep knowledge of Python's syntax, libraries, and quirks.

Here’s a comprehensive guide to Python golfing, from basic techniques to advanced tricks.


The Golden Rule of Golfing

Read the problem carefully. The goal is not just to make the code short, but to make it short and correct. A clever one-liner that fails on edge cases is worse than a slightly longer, robust solution.


Level 1: The Basics (Easy Savings)

These are the most common and effective techniques for shaving off characters.

Use Shorter Variable Names

This is the most obvious one. Use single-letter variables or abbreviations.

  • Before: for i in range(10): print(i)
  • After: for i in range(10):print(i) (saving a space is also key!)

Remove Unnecessary Whitespace

Python is whitespace-sensitive, but not all whitespace is required.

  • Spaces around operators: a = b + c -> a=b+c
  • Spaces after commas: f(a, b) -> f(a,b)
  • Spaces after colons in loops/conditionals: if a==b: pass -> if a==b:pass
  • Spaces after function definitions: def f(): pass -> def f():pass
  • Newlines: Often, you can chain statements on one line with . a=1;b=2;print(a+b)

Use lambda for Simple Functions

If a function is just one return statement, a lambda is often shorter.

  • Before:
    def f(x): return x*x
  • After:
    f=lambda x:x*x

    This saves 6 characters (def f( and ): return).

Use List Comprehensions

Instead of a for loop that builds a list, use a list comprehension. They are more concise and often faster.

  • Before:
    s = []
    for i in range(10):
        s.append(i*i)
  • After:
    s=[i*i for i in range(10)]

    This saves 10 characters.


Level 2: Intermediate Tricks (Significant Savings)

These techniques involve clever use of Python's features and libraries.

Leverage the eval Function

The eval() function can be a golfer's best friend. It parses and executes a string as Python code. This is extremely powerful for mathematical problems.

  • Problem: Calculate the sum of a and b.

  • Before: print(a+b)

  • After: eval('a+b') This is only useful if the string 'a+b' is shorter than a+b, which it isn't in this case. But for more complex expressions, it can be a huge win.

  • Problem: Calculate a^b (bitwise XOR).

  • Before: print(a^b)

  • After: eval('a**b') (No, this is exponentiation) Let's try again.

  • Better After: eval('a^b') (Same length, but shows the concept)

  • *Real Example (Calculate `ab+c`):**

    • print(a*b+c) (9 chars)
    • eval('a*b+c') (11 chars) -> Not a win.
    • eval('a*b+c') is a win when the expression is long and you can generate it dynamically.

Use Ternary Conditional Operator

For a simple if-else, the ternary operator is much shorter.

  • Before: x = a if a > b else b
  • After: x=[b,a][a>b] This is a classic golfing trick. It creates a list [b, a] and picks the element at index a > b. Since True is 1 and False is 0, this works perfectly. It's often shorter than the x=a if a>b else b syntax.

Abuse Truthy/Falsy Values

In Python, many objects have a "truthiness".

  • 0, 0, , [], , are False.
  • Almost everything else is True.

You can use this to avoid writing == 0 or .

  • Before: if n == 0: print("Zero")
  • After: if not n:print("Zero") (saves 3 chars)

Use map and filter

These functions apply another function to every item in an iterable (or a filtered subset of it).

  • Problem: Square every number in a list l.
  • Before: [i*i for i in l]
  • After: map(lambda i:i*i,l) (Often needs to be wrapped in list() to see the result, e.g., list(map(...)), so this isn't always a win).

Use the Walrus Operator (Python 3.8+)

This operator assigns a value to a variable as part of an expression. This is a game-changer for golfing.

  • Problem: Read a line from stdin, convert to int, and print it.
  • Before:
    i=int(input())
    print(i)
  • After:
    print(i:=int(input()))

    This saves 5 characters by combining two lines into one.


Level 3: Advanced & Obscure Tricks (The Pro Moves)

This is where you dive deep into Python's internals and less common features.

Use exec for Repetition

Similar to eval, exec runs a block of code. You can use it to repeat a command without a loop.

  • Problem: Print "Hello" 5 times.
  • Before: for _ in' ':print("Hello") (Uses the 5 spaces in the string to loop 5 times)
  • After: exec('print("Hello");'*5) (A very common golfing pattern)

Use String/Number Concatenation for Repetition

You can multiply strings or numbers to create a sequence.

  • Problem: Loop 10 times.
  • Before: for i in range(10):
  • After: for i in' ': (Uses the 10 spaces)
  • Even After: for i in 1e10: (Creates a float 0 and iterates over its digits, which is a bit weird but works)

Abuse print's sep and end Parameters

The print function is incredibly flexible. sep is the separator between items, and end is what's printed at the end.

  • Problem: Print "a" and "b" with no space between them.
  • Before: print("a",end="");print("b")
  • After: print("a","b",end="") (Saves many characters)

Use join with a Separator

A common pattern is to join a list of items.

  • Problem: Join a list of numbers l with a space.
  • Before: ' '.join(map(str, l))
  • After: *l, (Unpacking the list into print is often shorter)
    print(*l) # Prints items with a space separator

    Or, if you need the string itself: print(' '.join(l)) (Works if l contains strings)

Use globals() and locals()

These dictionaries hold the global and local variables in the current scope. You can access or modify variables by name as strings.

  • Problem: Assign the value 10 to the variable x.
  • Before: x=10
  • After: globals()['x']=10 (Much longer, but shows the concept. It's useful when the variable name is dynamic).

The Trick

This is a famous golfing trick. -~x is equivalent to x + 1.

  • ~x is the bitwise NOT of x, which is -x - 1.

  • So, -~x is -(-x - 1), which simplifies to x + 1.

  • Problem: Increment x.

  • Before: x+=1

  • After: x=-~x (Same length, but a fun trick. Can be useful in expressions).


Putting It All Together: A Case Study

Problem: Given a number n, print n to the power of n.

The "Normal" Solution (28 chars)

n=int(input())
print(n**n)

Golfing it Step-by-Step

  1. Combine lines with the walrus operator: We can read n and print in one go.

    print(n:=int(input())**n)

    This is 19 characters. A big improvement!

  2. Can we make the input part shorter? input() is 6 chars. Is there a shorter way to get input? No, not really. What about the conversion? int() is 4 chars.

  3. Let's look at the core logic: n**n. Is there a shorter way to write exponentiation? No, is the standard. What about pow(n,n)? That's also 6 chars, same as n**n.

  4. Let's re-examine the whole expression. print(n:=int(input())**n)

    • print(...) (5)
    • n:= (3)
    • int(input()) (10)
    • (2)
    • n (1)
    • Total: 5 + 3 + 10 + 2 + 1 = 21. Wait, my count was off. Let's count again.
    • p r i n t n i n t i n p u t n = 19 characters. Yes, it's 19.
  5. Is there a completely different approach? What if we don't use the walrus operator?

    print(int(input())**int(input()))

    This is 21 characters. Worse.

    i=int(input())
    print(i**i)

    This is 16 characters! This is shorter!

Conclusion: Sometimes the most obvious golfing tricks (like the walrus operator) don't lead to the shortest solution. The simplest approach can sometimes be the best. The final golfed answer is i=int(input());print(i**i) at 16 characters.


Where to Practice

The best place to practice is on code-golf.io or golf.shinh.org. These sites have hundreds of problems specifically designed for code golfing in many languages, including Python.

Happy golfing

分享:
扫描分享到社交APP
上一篇
下一篇