On 21 October 2012 19:33, Vincent Davis <span dir="ltr"><<a href="mailto:vincent@vincentdavis.net" target="_blank">vincent@vincentdavis.net</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div><font face="arial, helvetica, sans-serif">I am looking for a good way to get every pair from a string. For example,</font></div><div><font face="arial, helvetica, sans-serif">input:</font></div><div><font face="arial, helvetica, sans-serif">x = 'apple'</font></div>


<div><font face="arial, helvetica, sans-serif">output</font></div><div><font face="arial, helvetica, sans-serif">'ap'</font></div><div><font face="arial, helvetica, sans-serif">'pp'</font></div><div><font face="arial, helvetica, sans-serif">'pl'</font></div>


<div><font face="arial, helvetica, sans-serif">'le'</font></div><div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif">I am not seeing a obvious way to do this without multiple for loops, but maybe there is not :-)</font></div>


<div><font face="arial, helvetica, sans-serif">In the end I am going to what to get triples, quads....... also.</font></div></blockquote></div><div><br></div><div>The best way for <b>sliceable</b> objects is probably your way. However, not all items can be sliced.</div>

<br><div>One way is this:</div><div><br></div><div>Let us say you have a string:</div><div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<font face="courier new, monospace">>>> my_string = "abcdefghijklmnopqrstuvwxyz"<br>>>> my_string<br>'abcdefghijklmnopqrstuvwxyz'</font></blockquote><div> </div><div>If you are to "zip" that, you get a "zip object"</div>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><font face="courier new, monospace"> >>> zip(my_string)<br>

<zip object at 0x1b67f38></font></blockquote><div><br></div><div>So you want to turn it back into a list: </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<font face="courier new, monospace">>>> list(zip(my_string))<br>[('a',), ('b',), ('c',), ('d',), ('e',), ('f',), ('g',), ('h',), ('i',), ('j',), ('k',), ('l',), ('m',), ('n',), ('o',), ('p',), ('q',), ('r',), ('s',), ('t',), ('u',), ('v',), ('w',), ('x',), ('y',), ('z',)]</font></blockquote>

<div><br></div><div>So why would you want "zip" anyway? Let us see what it does with two inputs.</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<font face="courier new, monospace">>>> list(zip(my_string, my_string))<br>[('a', 'a'), ('b', 'b'), ('c', 'c'), ('d', 'd'), ('e', 'e'), ('f', 'f'), ('g', 'g'), ('h', 'h'), ('i', 'i'), ('j', 'j'), ('k', 'k'), ('l', 'l'), ('m', 'm'), ('n', 'n'), ('o', 'o'), ('p', 'p'), ('q', 'q'), ('r', 'r'), ('s', 's'), ('t', 't'), ('u', 'u'), ('v', 'v'), ('w', 'w'), ('x', 'x'), ('y', 'y'), ('z', 'z')]</font></blockquote>

<div><br></div><div>I see. It goes over the first and takes an item, then over the second and takes an item, and then puts them together. It then does this for all the items in each.</div><div><br></div></div><div>All we want to do is offset the second item:</div>

<div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><font face="courier new, monospace">>>> list(zip(my_string, my_string[1:]))<br>

[('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'e'), ('e', 'f'), ('f', 'g'), ('g', 'h'), ('h', 'i'), ('i', 'j'), ('j', 'k'), ('k', 'l'), ('l', 'm'), ('m', 'n'), ('n', 'o'), ('o', 'p'), ('p', 'q'), ('q', 'r'), ('r', 's'), ('s', 't'), ('t', 'u'), ('u', 'v'), ('v', 'w'), ('w', 'x'), ('x', 'y'), ('y', 'z')]</font></blockquote>

</div><div><br></div><div>And then convert the results to single strings:</div><div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<font face="courier new, monospace">>>> ["".join(strs) for strs in zip(my_string, my_string[1:])]<br>['ab', 'bc', 'cd', 'de', 'ef', 'fg', 'gh', 'hi', 'ij', 'jk', 'kl', 'lm', 'mn', 'no', 'op', 'pq', 'qr', 'rs', 'st', 'tu', 'uv', 'vw', 'wx', 'xy', 'yz']</font></blockquote>

</div><div><br></div><div>And this can be generalised in a more complicated way:</div><div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<font face="courier new, monospace">>>> ["".join(strs) for strs in zip(*[my_string[n:] for n in range(4)])]<br></font><font face="courier new, monospace">['abcd', 'bcde', 'cdef', 'defg', 'efgh', 'fghi', 'ghij', 'hijk', 'ijkl', 'jklm', 'klmn', 'lmno', 'mnop', 'nopq', 'opqr', 'pqrs', 'qrst', 'rstu', 'stuv', 'tuvw', 'uvwx', 'vwxy', 'wxyz']</font></blockquote>

</div><div><br></div><div>Which can work with iterables:</div><div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<font face="courier new, monospace">>>> from itertools import islice<br>>>> ["".join(strs) for strs in zip(*[islice(my_string, n, None) for n in range(4)])]<br>['abcd', 'bcde', 'cdef', 'defg', 'efgh', 'fghi', 'ghij', 'hijk', 'ijkl', 'jklm', 'klmn', 'lmno', 'mnop', 'nopq', 'opqr', 'pqrs', 'qrst', 'rstu', 'stuv', 'tuvw', 'uvwx', 'vwxy', 'wxyz']</font></blockquote>

</div><div><br></div><div>This will be much <i>faster</i> for short sequences made from massive strings and much <i>slower</i> for long sequences made from medium-sized strings.</div><div>The first method <b>slices</b>, which copies a part of the whole string. This is slow for large copies.</div>

<div>The second method<b> loops until it reaches the start</b>. This is slow when the start is a long way in.</div><div><br></div><div>However, if you want to use slice-able items, the best way is the one you've already worked out, as it does no extra copying or looping.</div>