The format_iter
recipe defines a simple wrapper around str.join
and str.format
that makes it easy to format an arbitrary iterable with a specified format string and item separator.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | # Remove the '*, ' keyword-only marker for 2.7 compatibility
# Make the default format string '{0!r}' for 2.6 compatibility
# Default values can obviously be adjusted according to taste
def format_iter(iterable, *, fmt='{!r}', sep=', '):
"""Format and join items in iterable with the given format string and separator"""
return sep.join(fmt.format(x) for x in iterable)
# Example usage
>>> format_iter(range(10))
'0, 1, 2, 3, 4, 5, 6, 7, 8, 9'
>>> format_iter(range(10), sep='|')
'0|1|2|3|4|5|6|7|8|9'
>>> format_iter(range(10), fmt='{:04b}', sep='|')
'0000|0001|0010|0011|0100|0101|0110|0111|1000|1001'
>>> format_iter(range(10), fmt='{0.real}+{0.imag}j')
'0+0j, 1+0j, 2+0j, 3+0j, 4+0j, 5+0j, 6+0j, 7+0j, 8+0j, 9+0j'
|
This recipe arose from my dissatisfaction with a piece of code I had written and asked about on Stack Overflow: http://stackoverflow.com/questions/7072938/including-a-formatted-iterable-as-part-of-a-larger-formatted-string
I think this recipe also showcases the expressive power and flexibility of the new-style string formatting over the old mod-style formatting - mod-style would break if the iterable contained tuples (or dicts) and you would have no ability to cherry-pick attributes or subitems as is shown in the last example.
Note that the usual workaround for the tuple/dict problem (forcing the use of a singleton tuple) would at least make the mod-style equivalent a little more reliable, but you'd still have no way to access the contents of those tuples or dictionaries. New-style formatting makes them available via field indexing.