python列表查找整数,Python:找出整数列表是否一致

I am trying to find out whether a list of integers is coherent or 'at one stretch', meaning that the difference between two neighboring elements must be exactly one and that the numbers must be increasing monotonically. I found a neat approach where we can group by the number in the list minus the position of the element in the list -- this difference changes when the numbers are not coherent. Obviously, there should be exactly one group when the sequence does not contain gaps or repetitions.

Test:

>>> l1 = [1, 2, 3, 4, 5, 6]

>>> l2 = [1, 2, 3, 4, 5, 7]

>>> l3 = [1, 2, 3, 4, 5, 5]

>>> l4 = [1, 2, 3, 4, 5, 4]

>>> l5 = [6, 5, 4, 3, 2, 1]

>>> def is_coherent(seq):

... return len(list(g for _, g in itertools.groupby(enumerate(seq), lambda (i,e): i-e))) == 1

...

>>> is_coherent(l1)

True

>>> is_coherent(l2)

False

>>> is_coherent(l3)

False

>>> is_coherent(l4)

False

>>> is_coherent(l5)

False

It works well, but I personally find that this solution is a bit too convoluted in view of the simplicity of the problem. Can you come up with a clearer way to achieve the same without significantly increasing the code length?

Edit: summary of answers

From the answers given below, the solution

def is_coherent(seq):

return seq == range(seq[0], seq[-1]+1)

clearly wins. For small lists (10^3 elements), it is on the order of 10 times faster than the groupby approach and (on my machine) still four times faster than the next best approach (using izip_longest). It has the worst scaling behavior, but even for a large list with 10^8 elements it is still two times faster than the next best approach, which again is the izip_longest-based solution.

Relevant timing information obtained with timeit:

Testing is_coherent_groupby...

small/large/larger/verylarge duration: 8.27 s, 20.23 s, 20.22 s, 20.76 s

largest/smallest = 2.51

Testing is_coherent_npdiff...

small/large/larger/verylarge duration: 7.05 s, 15.81 s, 16.16 s, 15.94 s

largest/smallest = 2.26

Testing is_coherent_zip...

small/large/larger/verylarge duration: 5.74 s, 20.54 s, 21.69 s, 24.62 s

largest/smallest = 4.28

Testing is_coherent_izip_longest...

small/large/larger/verylarge duration: 4.20 s, 10.81 s, 10.76 s, 10.81 s

largest/smallest = 2.58

Testing is_coherent_all_xrange...

small/large/larger/verylarge duration: 6.52 s, 17.06 s, 17.44 s, 17.30 s

largest/smallest = 2.65

Testing is_coherent_range...

small/large/larger/verylarge duration: 0.96 s, 4.14 s, 4.48 s, 4.48 s

largest/smallest = 4.66

Testing code:

import itertools

import numpy as np

import timeit

setup = """

import numpy as np

def is_coherent_groupby(seq):

return len(list(g for _, g in itertools.groupby(enumerate(seq), lambda (i,e): i-e))) == 1

def is_coherent_npdiff(x):

return all(np.diff(x) == 1)

def is_coherent_zip(seq):

return all(x==y+1 for x, y in zip(seq[1:], seq))

def is_coherent_izip_longest(l):

return all(a==b for a, b in itertools.izip_longest(l, xrange(l[0], l[-1]+1)))

def is_coherent_all_xrange(l):

return all(l[i] + 1 == l[i+1] for i in xrange(len(l)-1))

def is_coherent_range(seq):

return seq == range(seq[0], seq[-1]+1)

small_list = range(10**3)

large_list = range(10**6)

larger_list = range(10**7)

very_large_list = range(10**8)

"""

fs = [

'is_coherent_groupby',

'is_coherent_npdiff',

'is_coherent_zip',

'is_coherent_izip_longest',

'is_coherent_all_xrange',

'is_coherent_range'

]

for n in fs:

print "Testing %s..." % n

t1 = timeit.timeit(

'%s(small_list)' % n,

setup,

number=40000

)

t2 = timeit.timeit(

'%s(large_list)' % n,

setup,

number=100

)

t3 = timeit.timeit(

'%s(larger_list)' % n,

setup,

number=10

)

t4 = timeit.timeit(

'%s(very_large_list)' % n,

setup,

number=1

)

print " small/large/larger/verylarge duration: %.2f s, %.2f s, %.2f s, %.2f s" % (t1, t2, t3, t4)

print " largest/smallest = %.2f" % (t4/t1)

Test machine:

Linux 3.2.0 (Ubuntu 12.04)

Python 2.7.3 (gcc 4.1.2)

numpy 1.6.2 built with Intel compiler

CPU: E5-2650 @ 2.00GHz

24 GB of memory

解决方案

how bout

sorted_list = sorted(my_list)

return sorted_list == range(sorted_list[0],sorted_list[-1]+1)

or if its only coherent if it is already sorted

return my_list == range(my_list[0],my_list[-1]+1)

if you are using python 3 you will need list(range(...))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值