Wrapping around a list

Ned Batchelder ned at nedbatchelder.com
Wed Nov 27 12:26:26 CET 2013


On 11/27/13 6:14 AM, Chris Angelico wrote:
> On Wed, Nov 27, 2013 at 10:07 PM, Amjad Syed <amjadcsu at gmail.com> wrote:
>> Thanks Chris for the reply. But i would like sliding function to be scalable, as input string can be of 100 letters.
>
> A hundred isn't much to work with, and your code will be fairly
> simple. Give it a try with small strings, see how it goes; then try it
> on your full-size - I doubt there'll be a problem.
>
> Now, if you were talking about a hundred million letters, then maybe
> there'd be a problem. But even there, I'd start with the simple and
> clean approach, and only optimize for performance when it becomes
> obviously necessary (like when my MUD client was able to saturate one
> core of my CPU, just by me typing a lot of commands very rapidly -
> that needed fixing!).
>
> ChrisA
>

Using ChrisA's idea:

     def sliding_window(iterable, n, fill=None):
         values = list(iterable)
         num_values = len(values)
         if fill is not None:
             values.extend([fill]*(n-1))
         need_more = (2*num_values-1) - len(values)
         values.extend(values[:need_more])
         for start in range(num_values):
             yield values[start:start+n]

     l = list("LEQNABC")
     for n in range(2, len(l)+1):
         print [''.join(x) for x in sliding_window(l, n)]
     for n in range(2, len(l)+1):
         print [''.join(x) for x in sliding_window(l, n, fill="_")]

Produces:

['LE', 'EQ', 'QN', 'NA', 'AB', 'BC', 'CL']
['LEQ', 'EQN', 'QNA', 'NAB', 'ABC', 'BCL', 'CLE']
['LEQN', 'EQNA', 'QNAB', 'NABC', 'ABCL', 'BCLE', 'CLEQ']
['LEQNA', 'EQNAB', 'QNABC', 'NABCL', 'ABCLE', 'BCLEQ', 'CLEQN']
['LEQNAB', 'EQNABC', 'QNABCL', 'NABCLE', 'ABCLEQ', 'BCLEQN', 'CLEQNA']
['LEQNABC', 'EQNABCL', 'QNABCLE', 'NABCLEQ', 'ABCLEQN', 'BCLEQNA', 
'CLEQNAB']
['LE', 'EQ', 'QN', 'NA', 'AB', 'BC', 'C_']
['LEQ', 'EQN', 'QNA', 'NAB', 'ABC', 'BC_', 'C__']
['LEQN', 'EQNA', 'QNAB', 'NABC', 'ABC_', 'BC__', 'C___']
['LEQNA', 'EQNAB', 'QNABC', 'NABC_', 'ABC__', 'BC___', 'C____']
['LEQNAB', 'EQNABC', 'QNABC_', 'NABC__', 'ABC___', 'BC____', 'C_____']
['LEQNABC', 'EQNABC_', 'QNABC__', 'NABC___', 'ABC____', 'BC_____', 
'C______']

100 elements is really nothing, don't try to over-optimize it.  And if 
your inputs are really strings, not general iterables, you can use the 
same logic but with string operations, and you'll likely have better 
performance anyway.  Less general, true, but better for your actual problem.

--Ned.




More information about the Python-list mailing list