Split a list into chunks by a number of chars [Python]

Viewed 44

I've got a list of words (domains in my case) and I need to split this list into groups, each group should contain not more than N chars (=bytes). One important thing is that the last word in each group should not break in the middle. I mean there should not be situations like:

google.com
yahoo.com
bin

In my code I only managed to retrieve the first group, I don't know how to make a proper loop to split the list into multiple chunks.

domains = ['google.com','yahoo.com','bing.com','microsoft.com','apple.com','amazon.com']


domains = list(domains)
text = ""
chars_sent=0
max_chars=20

for each_domain in domains:
    if chars_sent > max_chars:
        chars_sent = 0
        break
    text += each_domain+"\n"
    chars_sent += len((str(each_domain)))
print(text)

Expected output:

google.com
yahoo.com <--- 19 chars in this part

bing.com <--- 8 chars in this part

microsoft.com <--- 13 chars in this part

apple.com
amazon.com <--- 19 chars in this part
3 Answers

You have to check whether adding the new element will exceed the maximum before adding it to the result.

And when you hit the limit you shouldn't break out of the loop, just add a blank line to the result.

domains = ['google.com','yahoo.com','bing.com','microsoft.com','apple.com','amazon.com']

text = ""
chars_sent=0
max_chars=20

for each_domain in domains:
    if chars_sent + len(each_domain) > max_chars:
        chars_sent = 0
        text += "\n"
    text += each_domain+"\n"
    chars_sent += len(each_domain)

print(text)

There's no need to use list(domain) since it's already a list, or str(each_domain) because it's already a string.

You're almost there! Here's another answer, if you want to get your result as nested lists (might be more pratical to use than plain text).

domains = ['google.com', 'yahoo.com', 'bing.com', 'microsoft.com', 'apple.com', 'amazon.com']
max_chars = 20

chunk_size = 0
chunks = [[]]
for domain in domains:
    if chunk_size + len(domain) > max_chars:
        chunk_size = 0
        chunks.append([])
    
    chunks[-1].append(domain)
    chunk_size += len(domain)

print(chunks)

Result:

[
    ['google.com', 'yahoo.com'],
    ['bing.com'],
    ['microsoft.com'],
    ['apple.com', 'amazon.com']
]

You can also use:

domains = ['google.com','yahoo.com','bing.com','microsoft.com','apple.com','amazon.com']
max_chars=20
out = [""]
for d in domains:
    if len(d) + len(out[-1].strip()) > max_chars:
        out.append(f"{d}\n")
    else:
        out[-1] = f"{out[-1].strip()}\n{d}\n"

print(*out, sep="\n")

google.com
yahoo.com

bing.com

microsoft.com

apple.com
amazon.com

Demo

Related