python - Stopping a loop when "items run out" even if it doesn't reach the proper if clause -
i want write code takes list of items , concatenates them (separated commas) long strings, each string not longer predefined length. example, list:
colors = ['blue','pink','yellow']
and max len of 10 chars, output of code be:
long string 0: blue,pink
long string 1: yellow
i created following code (below), pitfall cases total length of concatenated items shorter of max len allowed, or creates 1 or more long strings , total len of concatenation of residual items in list shorter max len.
what i'm trying ask this: in following code, how "stop" loop when items run out , yet concatenation short "else" clause isn't reached?
many :)
import pyperclip # theoretical bug: when single item longer max_length. never happen intended use of code. raw_list = pyperclip.paste() split_list = raw_list.split() unique_items_list = list(set(split_list)) # notice set unordered collections, , original order not maintained. not crucial purpose of code way now, remembering. see more: http://stackoverflow.com/a/7961390/2594546 print "there %d items in list." % len(split_list) print "there %d unique items in list." % len(unique_items_list) max_length = 10 # salesforce's filters allow 1000 chars, didn't want hard code in rest of code, in case. list_of_long_strs = [] short_list = [] # hold items max_length chars long str. total_len = 0 items_processed = [] # used sanity checking in unique_items_list: if total_len + len(i) + 1 <= max_length: # +1 length of comma short_list.append(i) total_len += len(i) + 1 items_processed.append(i) elif total_len + len(i) <= max_length: # if there's no place item+comma, means we're nearing end of max_length chars mark. maybe can fit item without unneeded comma. short_list.append(i) total_len += len(i) # should end loop here somehow? items_processed.append(i) else: long_str = ",".join(short_list) if long_str[-1] == ",": # appending long_str list of long strings, while making sure item can't end "," can affect salesforce filters. list_of_long_strs.append(long_str[:-1]) else: list_of_long_strs.append(long_str) del short_list[:] # in order empty list. total_len = 0 unique_items_proccessed = list(set(items_processed)) print "number of items concatenated:", len(unique_items_proccessed) def sanity_check(): if len(unique_items_list) == len(unique_items_proccessed): print "all items concatenated" else: # other option len(unique_items_list) > len(unique_items_proccessed) print "the following items weren't concatenated:" print ",".join(list(set(unique_items_list)-set(unique_items_proccessed))) sanity_check() print ",".join(short_list) # when loop doesn't end way should since < max_length. need find better way handle item in list_of_long_strs: print "long string %d:" % list_of_long_strs.index(item) print item print
at moment, don't i
in else
case, miss out items, , don't deal short_list
if isn't filled last item in loop.
the simplest solution restart short_list
i
in :
short_list = [i] total_len = 0
and check after for
loop whether there left in short_list
, , deal if so:
if short_list: list_of_long_strs.append(",".join(short_list))
you can simplify if
checking:
new_len = total_len + len(i) if new_len < max_length: ... elif new_len == max_length: ... else: ...
get rid of if
/else
block starting:
if long_str[-1] == ",":
(",".join(...)
means never happens)
and neaten last part of code using enumerate
(and i'd switch str.format
):
for index, item in enumerate(list_of_long_strs): print "long string {0}:".format(index) print item
more broadly, here's i'd do:
def process(unique_items_list, max_length=10): """process list comma-separated strings maximum length.""" output = [] working = [] item in unique_items_list: new_len = sum(map(len, working)) + len(working) + len(item) # ^ items ^ commas ^ new item? if new_len <= max_length: working.append(item) else: output.append(working) working = [item] output.append(working) return [",".join(sublist) sublist in output if sublist] def print_out(str_list): """print out list of strings indices.""" index, item in enumerate(str_list): print("long string {0}:".format(index)) print(item)
demo:
>>> print_out(process(["ab", "cd", "ef", "gh", "ij", "kl", "mn"])) long string 0: ab,cd,ef long string 1: gh,ij,kl long string 2: mn
Comments
Post a Comment