Welcome, guest | Sign In | My Account | Store | Cart

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.

Python, 17 lines
 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.