Reputation: 456
I want to check if a list contains incrementing elements, incremented by one each and starting with 0. So, e.g. [0, 1, 2, 3]
should return "valid", whereas e.g. [0, 1, 3, 4]
or [-1, 0, 1]
should return "not valid".
Is there an easy way to achieve that in Python? Maybe a built-in function?
Upvotes: 1
Views: 4391
Reputation: 527
I think it can be solved via a one-liner in a functional manner:
print not len(filter(lambda i: i!=-1, [x[i]-x[i+1] for i in range(len(x)-1)]))
given True
for x = [0, 1, 2, 3]
and False
for x = [0, 1, 3, 4]
Explanation:
[x[i]-x[i+1] for i in range(len(x)-1)]
makes a list of differences between successive elements, obviously we want to have all -1
...
Then we use filter
to select those elements which are different from -1
, if there is at least one, it is not a incrementing elements and so the length of such filtered list > 0
If yes, i.e. there are just -1
, the field is empty and we get length of 0.
Upvotes: 1
Reputation: 10951
How about using all
:
>>> l = [0, 1, 2, 3]
>>> not l[0] and all(y-x==1 for x,y in zip(l, l[1:]))
True
>>> l1 = [0,1,2,3,5,7]
>>> not l[0] and all(y-x==1 for x,y in zip(l1, l1[1:]))
False
>>> l2 = [0,1,2,3,4,7]
>>> not l[0] and all(y-x==1 for x,y in zip(l2, l2[1:]))
False
>>> l3=[-1,0,1,2]
>>> not l[0] and all(y-x==1 for x,y in zip(l3, l3[1:]))
False
>>> l2 = [0,1,2,3,4,5,7]
>>> not l[0] and all(y-x==1 for x,y in zip(l2, l2[1:]))
False
>>> l4=[0,2,3,4,5,7,8]
>>> not l[0] and all(y-x==1 for x,y in zip(l4, l4[1:]))
False
>>> l5=[0,2,3,4,5,6,7,8]
>>> not l[0] and all(y-x==1 for x,y in zip(l5, l5[1:]))
False
So you can put this into a function, this way:
def check_my_list(lst):
if not lst:
print 'List Empty'
return False
test = not lst[0] and all(y-x==1 for x,y in zip(lst,lst[1:])
return test
Upvotes: 3
Reputation: 6564
If the problem is truly as you describe it, this can be solved trivially using range
, like so:
myList = [...]
if myList == list(range(myList[-1] + 1)):
# Do stuff.
Upvotes: 12