I have some code which takes input from the user and stores it in a list. The list may have an odd or even number of elements, for example:
my_list = ['Beef','Chicken','Eggs','Lamb','Nuts','Pork']
(even number of elements)
or my_list = ['Beef','Chicken','Eggs','Lamb','Nuts','Pork','Potatoes']
(odd number of elements)
I want to store my_list
in a string variable, such so that when I print(var)
or create a tkinter messagebox, my program will output two columns like this:
-- Beef --Chicken
-- Eggs --Lamb
-- Nuts --Pork
-- Potatoes
I know how to manipulate the strings, but I'm stuck on creating the columns. I have tried this:
for x,y in zip(my_list[0::2], my_list[1::2]):
print("{0} {1}".format(x, y))
But that doesn't work for lists of odd-number length. I have also tried the more complicated:
#When my_list = ['Beef','Chicken','Eggs','Lamb','Nuts','Pork','Potatoes']
list1 = []
list2 = []
while len(my_list) != 0:
list1.append(my_list[0])
my_list.pop(0)
if len(my_list) == 0:
list2.append('')
else:
list2.append(my_list[0])
my_list.pop(0)
for i in range (len(list1)):
blank_space = 40 - len(list1[i-1])
string2 = "\n--" list1[i] ' '*blank_space '--' list2[i]
string1 = string1 string2
print(string1)
but the output I get is like this:
--Beef --Chicken
--Eggs --Lamb
--Nuts --Pork
--Potatoes --
which doesn't align the columns correctly.
Besides splitting it into columns, it is also important that the output is in the form:
--Element1 --Element2
--Element3 --Element4
and not in any other form. I'd really appreciate any help on where I'm making my mistake. If you need anymore clarification just tell me and I will add it into my question.
CodePudding user response:
How about something like the following, which uses the fact that out-of-range slicing does not throw an error:
my_list = ['Beef','Chicken','Eggs','Lamb','Nuts','Pork','Potatoes']
for i in range(0, len(my_list), 2):
print(' '.join(f"-- {s:10}" for s in my_list[i:i 2]))
Output:
-- Beef -- Chicken
-- Eggs -- Lamb
-- Nuts -- Pork
-- Potatoes
Or if you want to get a single string, you can nest join
:
output = '\n'.join(' '.join(f"-- {s:10}" for s in my_list[i:i 2]) for i in range(0, len(my_list), 2))
CodePudding user response:
Here ya go :-)
Variable columns, validates the longest word fits and should be pretty efficient
# Figure out the number of columns you wish to have in your table.
COLUMNS = 2
my_list = ['Beef','Chicken','Eggs','Lamb','Nuts','Pork','Potatoes']
# Figure our the length of the longest word in the list
longest_word_length = max(map(len,my_list))
# Create a format string that will add some spacing to the list
format_string = f'-- {{0:{longest_word_length 2}}}'
output = []
# Format all the items in the list
for index, item in enumerate(my_list, start=1):
output.append(format_string.format(item))
if index % COLUMNS == 0:
output.append('\n')
print(''.join(output))
You may as well use tabulate with the "plain"
format for an easy way to do it.
CodePudding user response:
I tried to put it in a comment but it was too long so it became its own answer. To expand on the other answers, I thought it was a good idea to explain what the code is doing.
Breaking up the code into parts, and starting with j1-lee's answer, we have:
for i in range(0, len(my_list), 2):
print(' '.join(f"-- {s:10}" for s in my_list[i:i 2]))
or
output = '\n'.join(' '.join(f"-- {s:10}" for s in my_list[i:i 2]) for i in range(0, len(my_list), 2))
There are several parts:
- f-strings are a handy way of formatting strings. The
f
before the quotes indicates an f-string. - Within the f-string there is a variable
s
that is part of the list comprehensionfor s in my_list[i:i 2]
.{s:10}
indicates that the length of the string is10
. (Or you could do something like what Bharel did and have another variable related to the length of the longest string and use that instead of10
.) This is probably a good idea if you plan to apply it to different lists. - (f"-- {s:10}" for s in my_list[i:i 2]) creates a generator, for example if you wrote
x = (f"-- {s:10}" for s in my_list[0:0 2])
and then triedfor i in x: print(i)
your output would be two strings:-- Beef
and-- Chicken
. - the
' '.join(...)
joins them together in a list, and like j1-lee says, if you nest them with multiple list comprehensions, you can get a single line.
I think you can probably get the most versatile by combining what j1-lee and Bharel did together. Note that I removed the space in the join
command since there is now a variable that defines the space between the columns.
def generate_columns(list_in, n_columns, column_space, output_as_list = True):
# Figure our the length of the longest word in the list
longest_word_length = max(map(len,list_in))
column_length = longest_word_length column_space
output = [''.join([f"-- {s:{column_length}}" \
for s in my_list[i:i n_columns]]) for i in range(0, len(my_list), n_columns)]
if output_as_list:
return output
return '\n'.join(o for o in output)
my_list = ['Beef','Chicken','Eggs','Lamb','Nuts','Pork','Potatoes']
print(generate_columns(my_list, 3, 5))
#['-- Beef -- Chicken -- Eggs ', '-- Lamb -- Nuts -- Pork ', '-- Potatoes ']
print(generate_columns(my_list, 2, 3, output_as_list = False))
#-- Beef -- Chicken
#-- Eggs -- Lamb
#-- Nuts -- Pork
#-- Potatoes