Python: Check whether list is sequential or not

2019-05-11 07:40发布

问题:

Want a function / statement, to check whether all the values of mylist are sequential or not, which is hexadecimal list. For example:

def checkmylist(mylist):
    #code returns True or False


mylist1 = ['03', '04', '05', '06', '07', '08', '09', '0a', '0b', '0c','0d', '0e', '0f']
mylist2 = ['03', '05', '06', '07', '08', '09', '0a', '0b', '0c','0d', '0e', '0f']

checkmylist(mylist1)
#expected to returns pass
checkmylist(mylist2)
#expected to returns fail

回答1:

def checkmylist(mylist):
    it = (int(x, 16) for x in mylist)
    first = next(it)
    return all(a == b for a, b in enumerate(it, first + 1))

With the first statement we convert the hex numbers to a generator of integers. With next(it) we take the first element of the generator. Then we enumerate the rest of the elements starting the numbering from first + 1. We conclude that we have a sequential list if the numbering of each element is the same as the element itself.



回答2:

You can use iter to create an iterator of your list (from second index to end) and then use all function to check if you have a sequence, note that int(next(it),16) (or as a more efficient way as mentioned in comment use functools.partial(int, base=16))will convert your string to integer with base 16 then you can do operation on them :

>>> import functools
>>> int16 = functools.partial(int, base=16)
>>> def checker(li):
...    it=iter(li[1:])
...    return all(int16(next(it))-int16(i)==1 for i in li[:-1])

Demo:

mylist1 = ['03', '04', '05', '06', '07', '08', '09', '0a', '0b', '0c','0d', '0e', '0f']
mylist2 = ['03', '05', '06', '07', '08', '09', '0a', '0b', '0c','0d', '0e', '0f']
>>> checker(mylist1)
True
>>> checker(mylist2)
False


回答3:

One hack to do it is. This finds the total elements in the list. As you mention that it has t be sequential, the last element must be length of the list more than the first element.

>>> def checkmylist(l):
...     a = [int(i,16) for i in sorted(set(l))]
...     return (len(a) == (a[-1]-a[0]+1))
... 
>>> checkmylist(mylist1)
True
>>> checkmylist(mylist2)
False
>>> checkmylist(['2', '2', '4'])
False


回答4:

mylist1 = ['03', '04', '05', '06', '07', '08', '09', '0a', '0b', '0c','0d', '0e', '0f']
mylist2 = ['03', '05', '06', '07', '08', '09', '0a', '0b', '0c','0d', '0e', '0f']

def checkmylist(li):
    start=int(li[0],16)
    for e in li[1:]:
        a=int(e,16)
        if a==start+1:
            start=a
        else:
            return False
    return True


assert checkmylist(mylist1)==True
#expected to returns pass
assert checkmylist(mylist2)==False
#expected to returns fail


回答5:

Similar to @JuniorCompressor but using a list comprehension, your base construct would be:

bool_match_to_myList = [1 if int(i, 16) else 0 for i in mylist]

You could check to see if that is true/false easy enough:

myList_is_sequential = sum([1 if int(i, 16) else 0 for i in mylist]) < 1

Or you can find the indexes where it is off (not sequential) with the help of numpy

import numpy as np
bool_match_to_myList_np = np.array([1 if int(i, 16) else 0 for i in mylist])
np.where(bool_match_to_myList == 0)[0]