Welcome, guest | Sign In | My Account | Store | Cart

Creates inclusive regular sequences or fully closed ranges which differs from the half-open ranges of Python. Also accepts floating point arguments.

Python, 107 lines
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
def seq(*args, **kwargs):
    """
        seq(n1, n2, base=, by=, length=, ztol=)    

    Minimum number is 1 and maximum number of args is 2.
    Any misspecification will result in an empty list. 
    Current version has no extensive error checking!
    """
    
    # Undefined key?
    unknownKeys = [key for key in kwargs.keys() if key not in ["base","length","by","ztol"]]
    if unknownKeys:
        return []
    
    # Tolerance for floating point computations.
    if kwargs.has_key("ztol"):
        ztol = kwargs["ztol"]
    else:
        ztol = 1.0e-14
    
    # Normally, base is 0 since Python indexing is 0-based.
    if kwargs.has_key("base"):
        base = kwargs["base"]
    else:
        base = 0
    
    nargs, nkwargs = len(args), len(kwargs)
    if nargs == 1:  
        n1 = float(args[0])
        if kwargs.has_key("length"):
            L = kwargs["length"]
            if kwargs.has_key("by"):
                d = kwargs["by"]
            else:
                d = 1.0
            return [n1 + i * d for i in range(L)]
        
        elif kwargs.has_key("by"):
            d = kwargs["by"]
            if abs(d) < ztol: # too small by.
                return []
            if (n1 > base and d > 0) or (n1 < base and d < 0):
                return [] # wrong sign for value of by
            L = int((float(base-n1) / float(d)) + 1 + ztol)
            return [n1 + i * d for i in range(L) ]

        else:
            L = int((abs(n1 - base)) + 1 + ztol)
            if n1 > base:
                return [base + i  for i in range(L) ]
            else:
                return [base - i  for i in range(L) ]
            
    elif nargs == 2:  
        n1 = args[0]
        n2   = args[1]

        nparms = 0
        if kwargs.has_key("by") and kwargs.has_key("length"):
            return []  # Too many parameters
        if kwargs.has_key("by"):
            d = kwargs["by"]
            if n2 > n1 and d < 0:
                return []  # Wrong sign for by value.
            L = int((float(n2 - n1) / d) + 1 + ztol)
        elif kwargs.has_key("length"):
            L = kwargs["length"]
            if L <= 0:
                return []
            d = float((n2 - n1)) /  float(L)
        else:
            if n2 < n1:
                d = -1
            elif n2 > n1:
                d = 1
            else:
                d = 0
            L = int(abs(n2 - n1) + 1 + ztol)                
        return [n1 + i*d for i in range(L) ]
    return []
        

if __name__ == "__main__":
    print "seq(2)",                      seq(2)
    print "seq(2, base=1)",              seq(2, base=1)
    print "seq(2.6)",                    seq(2.6)
    print "seq(2.6, length=4)",          seq(2.6, length=4)
    print "seq(2.6, length=4, by=0.1)",  seq(2.6, length=4, by=0.1)
    print "seq(2.6, length=4, by=-0.1)", seq(2.6, length=4, by=-0.1)
    print "seq(2.6, length=4, by= 0)",   seq(2.6, length=4, by=0)

    print "seq(2,   by=0.1)",            seq(2.6,  by= 0.1)
    print "seq(2.6, by=-0.1)",           seq(2.6, by=-0.1)
    print "seq(2.6, by=-0.1, base = 1)", seq(2.6, by=-0.1, base=1)
    
    print "seq(-2)",                     seq(-2)
    print "seq(-2, base=1)",             seq(-2, base=1)
    print "seq(-2.6)",                   seq(-2.6)
    print "seq(-2.6, by=0.1, base = 1)", seq(-2.6, by=0.1, base=1)
    print "seq(-2.6, by=-0.1)",          seq(-2.6, by=-0.1)
    print "seq(2.6,  by= 0)",            seq(2.6, by=0)
    
    print "seq(-2.6, 5)",                seq(-2.6, 5)
    print "seq(5, -2.6)",                seq(5, -2.6)
    print "seq(-2.6, 5.1, by=0.1)",      seq(-2.6, 5.1, by=0.1)
    print "seq(-2.6, 5, by=-0.1)",       seq(-2.6, 5, by=-0.1)
    print "seq(-2.6, 5, by=-0.1, length=10)",seq(-2.6, 5, by=-0.1, length=10)

The seq() function returns a regular inclusive sequence as a list. It differs from a Python range in that the sequence includes all end-points. User can optionally specify the length, step and base (if only one non-keyword argument is given).

Run the test example to see the effects of key arguments. The function is somewhat similar to the seq() function in R. The behavior is not he same as the arange() function of scipy (or Numeric).

See also frange() function in ASPN Cookbook Python Recipe #66472

Created by Ernesto Adorio on Tue, 2 May 2006 (PSF)
Python recipes (4591)
Ernesto Adorio's recipes (9)

Required Modules

  • (none specified)

Other Information and Tasks