![]() ![]() Iterator, it.repeat(head), it.repeat(sentinel), it.repeat(running)) If the name resolution for sentinel and running from inside the mapped function is a concern, they can be included as arguments to that function: iterators = [map(lambda x, h, s, r: next(r) or h if x is s else x, Iterators = # here the conversion to map objects remains unchanged If leaking StopIteration from the mapped function in order to terminate the map iterator feels too awkward then we can slightly modify the definition of running to yield an additional sentinel and use the 2-argument form of iter in order to stop on sentinel: running = it.chain(it.repeat(None, len(iterators) - 1), (sentinel,)) Iterators = [map(lambda x, h: next(running) or h if x is sentinel else x, # StopIteration causes the map to stop iterating Running = it.repeat(None, len(iterators) - 1) # For the sentinel corresponding to the last iterator in 'iterators' this will leak a StopIteration. # Create a dedicated iterator object that will be consumed each time a 'sentinel' object is found. ![]() Iterators = Heads = # requires each of the iterables to be non-empty Iterators = # make sure we're operating on iterators In summary, the following function performs the steps described above: import itertools as it if item is sentinel then consume a dedicated iterator that yields one item fewer than the total number of iterators via next (hence leaking StopIteration for the last sentinel) and replace the sentinel with the corresponding head.įinally we can just zip the iterators together - it will stop on the last one hitting its sentinel object, i.e.So we can map the chained iterators over a function that checks for each item whether it is sentinel and performs the following steps: ![]() Alternatively we can use the 2-argument form of iter to stop on a sentinel object (see below). For this we can (ab)use the fact that map stops iterating if the mapped function raises (or leaks) a StopIteration, such as from next invoked on an already exhausted iterator. This uses it.repeat to replay the first item ad infinitum once the end of the iterator has been reached, so we need to introduce a way to stop that process once the last iterator hits its sentinel object. You can peek into each of the iterators via next in order to extract the first item ("head"), then create a sentinel object that marks the end of the iterator and finally chain everything back together in the following way: head -> remainder_of_iterator -> sentinel -> it.repeat(head). Is there any other process (like mapping any function or so) to the parameter fillvalue of the zip_longest function so that I don't have to iterate through the list to pad each sub-list up to the length of the longest sub-list before that and this thing can be done in a line with only zip_longest? In stead had I done list(zilo(*cont_det, fillvalue='')) I would have gotten this : [('TASU 117000 0', '40HS', 'Ha2ardous Materials'), I have got the result with this code : from itertools import zip_longest as ziloĬont_det = list(pad(cont_row, cont_row, max_))Ĭont_det = list(map(list, list(zilo(*cont_det)))) The logic behind this is zip_longest the list of lists but in case there is any sub-list whose length is less than the maximum of all lengths of the sub-lists (which is 5 here for first sub-list), then in stead of default fillvalue=None take the first item of that sub-list - as seen in case of second sub-list all reflected filled values are same and for the third one, the last three are filled by the first value. This is just a sample case for demonstration. Practically cont_det is a huge list with lots of sub-lists with irregular length of each sub-list. I have this list of lists : cont_det =, , ] ![]()
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |