Bug in slice type

Bryan Olson fakeaddress at nowhere.org
Wed Aug 24 11:03:02 EDT 2005


Kay Schluehr wrote:
 > Steven Bethard wrote:
 >>"The slice of s from i to j with step k is defined as the sequence of
 >>items with index x = i + n*k such that 0 <= n < (j-i)/k."
 >>
 >>This seems to contradict list behavior though.
 >>     range(10)[9:-1:-2] == []
 >
 >
 > No, both is correct. But we don't have to interpret the second slice
 > argument m as the limit j of the above definition.

Even if "we don't have to," it sure reads like we should.


 > For positive values
 > of m the identity
 > m==j holds. For negative values of m we have j = max(0,i+m).

First, the definition from the doc is still ambiguous: Is the
division in

     0 <= n < (j-i)/k

real division, or is it Python integer (truncating) division? It
matters.

Second, the rule Kay Schluehr states is wrong for either type
of division. Look at:

     range(5)[4 : -6 : -2]

Since Python is so programmer-friendly, I wrote some code to
make the "look at" task easy:



slice_definition = """"
The slice of s from i to j with step k is defined as the sequence of
items with index x = i + n*k such that 0 <= n < (j-i)/k.
"""

Kay_Schluehr_rule = """
For positive values of m the identity m==j holds. For negative values
of m we have j = max(0,i+m).
"""

def m_to_j(i, m):
     """ Compute slice_definition's 'j' according to Kay_Schluehr_rule
         when the slice of sequence is specified as,
             sequence[i : m : k].
     """
     if m > 0:
         j = m
     else:
         j = max(0, i + m)
     return j

def extract_slice(sequence, i, m, k, div_type='i'):
     """ Apply the slice definition with Kay Schluehr's rule to find
         what the slice should be. Pass div_type of 'i' to use integer
         division, or 'f' for float (~real) division, in the
         slice_definition expression,
             (j-i)/k.
     """
     j = m_to_j(i, m)
     result = []
     n = 0
     if div_type == 'i':
         end_bound = (j - i) / k
     else:
         assert div_type == 'f', "div_type must be 'i' or 'f'."
         end_bound = float(j - i) / k
     while n < end_bound:
         result.append(sequence[i + n * k])
         n += 1
     return result

def show(sequence, i, m, k):
     """ Print what happens, both actually and according to stated rules.
     """
     print "Checking: %s[%d : %d : %d]" % (sequence, i, m, k)
     print "actual                   :", sequence[i : m : k]
     print "Kay's rule, int division :", extract_slice(sequence, i, m, k)
     print "Kay's rule, real division:", extract_slice(sequence, i, m, 
k, 'f')
     print



show(range(5), 4, -6, -2)



-- 
--Bryan



More information about the Python-list mailing list