Extract the middle N chars of a string
Peter Otten
__peter__ at web.de
Wed May 18 12:41:21 EDT 2016
Steven D'Aprano wrote:
> Extracting the first N or last N characters of a string is easy with
> slicing:
>
> s[:N] # first N
> s[-N:] # last N
>
> Getting the middle N seems like it ought to be easy:
>
> s[N//2:-N//2]
>
> but that is wrong. It's not even the right length!
>
> py> s = 'aardvark'
> py> s[5//2:-5//2]
> 'rdv'
>
>
> So after spending a ridiculous amount of time on what seemed like it ought
> to be a trivial function, and an embarrassingly large number of off-by-one
> and off-by-I-don't-even errors, I eventually came up with this:
>
> def mid(string, n):
> """Return middle n chars of string."""
> L = len(string)
> if n <= 0:
> return ''
> elif n < L:
> Lr = L % 2
> a, ar = divmod(L-n, 2)
> b, br = divmod(L+n, 2)
> a += Lr*ar
> b += Lr*br
> string = string[a:b]
> return string
>
>
> which works for me:
>
>
> # string with odd number of characters
> py> for i in range(1, 8):
> ... print mid('abcdefg', i)
> ...
> d
> de
> cde
> cdef
> bcdef
> bcdefg
> abcdefg
> # string with even number of characters
> py> for i in range(1, 7):
> ... print mid('abcdef', i)
> ...
> c
> cd
> bcd
> bcde
> abcde
> abcdef
>
>
>
> Is this the simplest way to get the middle N characters?
>>> def mid(s, n):
... shave = len(s) - n
... if shave > 0:
... shave //= 2
... s = s[shave:shave+n]
... return s
...
>>> def show(s):
... for i in range(len(s)+1):
... print(i, repr(s), "-->", repr(mid(s, i)))
...
>>> show("abcdefg")
0 'abcdefg' --> ''
1 'abcdefg' --> 'd'
2 'abcdefg' --> 'cd'
3 'abcdefg' --> 'cde'
4 'abcdefg' --> 'bcde'
5 'abcdefg' --> 'bcdef'
6 'abcdefg' --> 'abcdef'
7 'abcdefg' --> 'abcdefg'
>>> show("abcdef")
0 'abcdef' --> ''
1 'abcdef' --> 'c'
2 'abcdef' --> 'cd'
3 'abcdef' --> 'bcd'
4 'abcdef' --> 'bcde'
5 'abcdef' --> 'abcde'
6 'abcdef' --> 'abcdef'
Not exactly the same results as your implementation though.
More information about the Python-list
mailing list