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. -- https://mail.python.org/mailman/listinfo/python-list