2010-03-11 3 views
1

testGroupList - это список целых чисел. Мне нужно проверить числа в testGroupList, это последовательные, а не повторяющиеся числа. Игнорируйте отрицательное целое число.Проверьте, не дублируется ли целое число в списке, а последовательный

Например, [1,2, -1,2,3,4] является ошибкой, так как дублируется 2, но [-1,3,2,4,1,5] в порядке.

Я реализовал его следующим образом, и это довольно уродливо. Есть ли какой-нибудь умный способ сделать это?

 
    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, 
+0

К сожалению, этот вопрос остается неясным. Вы имели в виду, что вам нужно проверить, что: для всех чисел в списке, которые больше нуля, эти цифры упорядочены и последовательно подсчитываются вверх? Таким образом, [3,4, -2,0,5] проходит, но [3,4,4,5], [3,5] и [3,5,4] нет? –

ответ

1

Для python2.7 или 3,1 Вы можете использовать счетчик, хотя печать должна быть изменена в случае 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()) 

Для старых Python использования 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(), 
0
 
for i, v in enumerate(buff): 
    if i != v - 1: 
     print "MISSING OR DUPLICATE" 
+0

Отредактировано использование buff вместо testGroupList –

+0

В отличие от исходного кода OP, это не отфильтровывает неположительные и не заботится о порядке элементов. – ephemient

+0

Он отфильтровывает неположительные свойства после моего редактирования, чтобы использовать бафф из примера вместо testGroupList –

0

Если вам не нужны причудливые сообщения об ошибках, вы можете реализовать их как две простые проверки:

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") 
1

Если вы ищете более элегантны, как в меньшем коде, то вы можете просто сделать это:

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), 

который довольно близко к оригиналу. Я использовал i вместо id, потому что id является стандартной функцией в Python.

0

Если вы просто пытаетесь определить, что в списке нет дубликатов, вы можете создать набор() с элементами списка и сравнить длину этих двух. Такая же длина означает отсутствие дубликатов.

Определение, если они являются последовательными, может смотреть на разность максимальных и минимальных значений списка, которая должна быть на единицу меньше длины.

«Разность настроек» может использоваться для поиска отсутствующих целых чисел.

Вот некоторые краткие определения:

def all_different(any_list): 
    '''returns True if all items in the list are different. 
    (Note: this assumes input is a list''' 
    return len(any_list) == len(set(any_list)) 

def any_duplicate(any_list): 
    '''returns True if any items in the list are repeated. 
    (Note: this assumes input is a list''' 
    return len(any_list) != len(set(any_list)) 

def sequential_ints(list_of_ints): 
    '''returns True if input is a sequential list of ints. 
    (Note: this assumes input is a list, and only of ints''' 
    return len(list_of_ints)-1==max(list_of_ints)-min(list_of_ints) 

def find_missing(list_of_ints): 
    '''returns a list of any integers "missing", assuming 
    input was "supposed to be" sequential list of ints. 
    (Note: this assumes input is a list, and only of ints''' 
    return list(set(range(min(list_of_ints),max(list_of_ints)+1))-set(list_of_ints)) 

Этот тестовый код:

list1 = [1, 2, 3, 4, 5, 6] 
print("all_different:", all_different(list1)) 
print("any_duplicate:", any_duplicate(list1)) 
print("sequential_ints:", sequential_ints(list1)) 
print("find_missing: ", find_missing(list1)) 
print() 

list2 = [1, 2, 3, 4, 5, 6, 2] 
print("all_different:", all_different(list2)) 
print("any_duplicate:", any_duplicate(list2)) 
print("sequential_ints:", sequential_ints(list2)) 
print("find_missing: ", find_missing(list2)) 
print() 

list3 = [1, 3, 4, 6] 
print("all_different:", all_different(list3)) 
print("any_duplicate:", any_duplicate(list3)) 
print("sequential_ints:", sequential_ints(list3)) 
print("find_missing: ", find_missing(list3)) 

Дает:

all_different: True 
any_duplicate: False 
sequential_ints: True 
find_missing: [] 

all_different: False 
any_duplicate: True 
sequential_ints: False 
find_missing: [] 

all_different: True 
any_duplicate: False 
sequential_ints: False 
find_missing: [2, 5] 
Смежные вопросы