tags:

views:

84

answers:

4

testGroupList is a list of integer. I need to check the numbers in testGroupList is sequential and not duplicate numbers. Ignore the negative integer.

For example, [1,2,-1,2,3,4] is an error as 2 is duplicated, but [-1,3,2,4,1,5] is OK.

I implemented it as follows, and it's pretty ugly. Is there any clever way to do this?

    buff = filter(lambda x: x > 0, testGroupList) 
    maxval = max(buff) 
    for i in range(maxval): 
        id = i+1 
        val = buff.count(id) 
        if val == 1: print id, 
        elif val >= 2: print "(Test Group %d duplicated %d times)" % (id, val), 
        elif val == 0: print "(Test Group %d missing)" % id,
+1  A: 

For Python2.7 or 3.1 you can use Counter, although the print needs to be changed in the case of Python3

from collections import Counter
counter = Counter(x for x in testGroupList if x>=0)
minval = min(Counter) 
maxval = max(Counter)
messages={0:"(Test Group %(id)d missing)",
          1:"%(id)d",
          2:"(Test Group %(id)d duplicated %(val)d times)"}
for id in range(minval,maxval+1): 
    val = counter[id]
    print(messages[min(val,2)]%vars())

For older Python use defaultdict

from collections import defaultdict
counter = defaultdict(int)
for k in testGroupList:
    if k>=0:counter[k]+=1

minval = min(counter) 
maxval = max(counter)
messages={0:"(Test Group %(id)d missing)",
          1:"%(id)d",
          2:"(Test Group %(id)d duplicated %(val)d times)"}
for id in range(minval,maxval+1): 
    val = counter[id]
    print messages[min(val,2)]%vars(),
gnibbler
A: 
for i, v in enumerate(buff):
    if i != v - 1:
        print "MISSING OR DUPLICATE"
Tuomas Pelkonen
Edited to use buff instead of testGroupList
Tuomas Pelkonen
Unlike OP's original code, this does not filter out nonpositives and cares about the order of elements.
ephemient
It does filter out nonpositives after my edit to use buff from the example instead of testGroupList
Tuomas Pelkonen
+1  A: 

If you don't need fancy error reporting, then you can implement it as two simple checks:

positiveValues = [x for x in testGroupList if x > 0]
if len(positiveValues) != len(set(positiveValues)):
    print("Input has duplicate values")
elif len(positiveValues) != max(positiveValues):
    print("Input has missing values")
Ants Aasma
+1  A: 

If you're looking for more elegant as in smaller code, then you can just do this:

buff = [x for x in testGroupList if x > 0]
for i, val in enumerate([buff.count(x) for x in xrange(1,max(buff))]):
    if val == 1: print i+1, 
    elif val > 1: print "(Test Group %d duplicated %d times)" % (i+1, val), 
    elif val == 0: print "(Test Group %d missing)" % (i+1),

which is pretty close to your original. I used i instead of id because id is a standard function in Python.

Justin Peel