使用timeit.Timer时遭遇SyntaxError: EOL扫描字符串字面量错误
Hey there! I’ve run into this exact SyntaxError: EOL while scanning string literal issue with timeit.Timer before—those multi-line setup strings can be tricky. Let’s break down how to fix the error first, then walk through a solid way to compare map and list comprehensions.
1. Fixing the Multi-Line Setup Syntax Error
The most common culprit here is not properly wrapping multi-line setup code in triple quotes (either ''' or """), or having inconsistent indentation that confuses the string parser. Here’s how to do it right:
- Always use triple quotes for multi-line setup/stmt strings. This lets you write clean, line-separated code without escaping newlines.
- If you’re writing this inside a function or indented block, use
textwrap.dedentto strip extra leading whitespace (this prevents indentation-related syntax errors).
Example of a correct setup:
import timeit import textwrap # Multi-line setup code wrapped in triple quotes, cleaned up with dedent setup = textwrap.dedent(''' def square(x): return x ** 2 test_numbers = list(range(10000)) ''') # Define the statements we want to time stmt_map = 'list(map(square, test_numbers))' stmt_list_comp = '[square(x) for x in test_numbers]'
Why this works:
- Triple quotes preserve the line breaks and indentation of your code.
textwrap.dedentremoves the leading whitespace that comes from indenting the string in your script, so the setup code runs as if it’s top-level.
If you still get errors, double-check:
- You haven’t accidentally mixed single/double quotes inside the triple-quoted string (e.g., using
'inside'''without escaping—though triple quotes usually let you avoid this). - The triple quotes are properly closed (no missing
'''or"""at the end).
2. Timing map vs List Comprehensions
Now that the setup is fixed, let’s run the timers. You can use either timeit.Timer or the simpler timeit.timeit function. Here’s both approaches:
Using timeit.Timer
# Initialize timers for each statement timer_map = timeit.Timer(stmt=stmt_map, setup=setup) timer_list_comp = timeit.Timer(stmt=stmt_list_comp, setup=setup) # Run the timing (number=1000 means run 1000 times) time_map = timer_map.timeit(number=1000) time_list_comp = timer_list_comp.timeit(number=1000) print(f"map took: {time_map:.4f} seconds") print(f"List comprehension took: {time_list_comp:.4f} seconds")
Using timeit.timeit (Shorter Syntax)
time_map = timeit.timeit(stmt=stmt_map, setup=setup, number=1000) time_list_comp = timeit.timeit(stmt=stmt_list_comp, setup=setup, number=1000) print(f"map: {time_map:.4f}s | List comp: {time_list_comp:.4f}s")
Bonus: Using timeit.repeat for More Reliable Results
For more consistent timing (since system load can affect individual runs), use timeit.repeat to get multiple runs and take the average:
repeat_map = timeit.repeat(stmt=stmt_map, setup=setup, number=1000, repeat=5) repeat_list_comp = timeit.repeat(stmt=stmt_list_comp, setup=setup, number=1000, repeat=5) avg_map = sum(repeat_map) / len(repeat_map) avg_list_comp = sum(repeat_list_comp) / len(repeat_list_comp) print(f"Average map time: {avg_map:.4f}s") print(f"Average list comp time: {avg_list_comp:.4f}s")
Quick Note on Performance
In most cases, list comprehensions are slightly faster than map (especially when using a lambda with map), but the difference is often negligible unless you’re working with extremely large datasets. The above code will let you measure the exact difference for your specific use case.
内容的提问来源于stack exchange,提问作者John F

