On 2016-05-18 16:47, 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?
I think your results are inconsistent.
For an odd number of characters you have "abc" + "de" + "fg", i.e. more
on the left, but for an even number of characters you have "a" + "bcd" +
"ef", i.e. more on the right.
My own solution is:
def mid(string, n):
"""Return middle n chars of string."""
if n <= 0:
return ''
if n > len(string):
return string
ofs = (len(string) - n) // 2
return string[ofs : ofs + n]
If there's an odd number of characters remaining, it always has more on
the right.
--
https://mail.python.org/mailman/listinfo/python-list