Reputation: 66515
I've a list of strings which I want to group by their suffix and then print the values right-aligned, padding the left side with spaces.
What is the pythonic way to do that?
My current code is:
def find_pos(needle, haystack):
for i, v in enumerate(haystack):
if str(needle).endswith(v):
return i
return -1
# Show only Error and Warning things
search_terms = "Error", "Warning"
errors_list = filter(lambda item: str(item).endswith(search_terms), dir(__builtins__))
# alphabetical sort
errors_list.sort()
# Sort the list so Errors come before Warnings
errors_list.sort(lambda x, y: find_pos(x, search_terms) - find_pos(y, search_terms))
# Format for right-aligning the string
size = str(len(max(errors_list, key=len)))
fmt = "{:>" + size + "s}"
for item in errors_list:
print fmt.format(item)
An alternative I had in mind was:
size = len(max(errors_list, key=len))
for item in errors_list:
print str.rjust(item, size)
I'm still learning Python, so other suggestions about improving the code is welcome too.
Upvotes: 2
Views: 1279
Reputation: 799470
Very close.
fmt = "{:>{size}s}"
for item in errors_list:
print fmt.format(item, size=size)
Upvotes: 8
Reputation: 602685
The two sorting steps can be combined into one:
errors_list.sort(key=lambda x: (x, find_pos(x, search_terms)))
Generally, using the key
parameter is preferred over using cmp
. Documentation on sorting
If you are interested in the length anyway, using the key
parameter to max()
is a bit pointless. I'd go for
width = max(map(len, errors_list))
Since the length does not change inside the loop, I'd prepare the format string only once:
right_align = ">{}".format(width)
Inside the loop, you can now do with the free format()
function (i.e. not the str
method, but the built-in function):
for item in errors_list:
print format(item, right_align)
str.rjust(item, size)
is usually and preferrably written as item.rjust(size)
.
Upvotes: 7