可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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]