我正在寻找更好的方法,可能正在使用列表推导?
>>> x = [1, 1, 1, 1, 1, 1]
>>> x
[1, 1, 1, 1, 1, 1]
>>> for i in x:
... if i!=1:
... print "fail"
...
>>>
>>> x = [1, 1, 1, 1, 1, 0]
>>> for i in x:
... if i!=1:
... print "fail"
...
fail
>>>
答案 0 :(得分:78)
>>> x = [1, 1, 1, 1, 1, 1]
>>> all(el==1 for el in x)
True
这会将all
函数与generator expression。
如果您在列表中始终只有零和一个(或者如果您只想检查列表中是否没有任何零),那么只需使用 all
其他技巧:
>>> x = [1, 0, 1, 1, 1, 0]
>>> all(x)
False
基准:
这些数字表示运行解决方案所花费的时间以毫秒为单位(平均1000 timeit
次运行)
Python 3.2.3
all(el==1 for el in x): 0.0003 0.0008 0.7903 0.0804 0.0005 0.0006
x==[1]*len(x): 0.0002 0.0003 0.0714 0.0086 0.0045 0.0554
not([1 for y in x if y!=1]): 0.0003 0.0005 0.4142 0.1117 0.1100 1.1630
set(x).issubset({1}): 0.0003 0.0005 0.2039 0.0409 0.0476 0.5310
y = set(x); len(y)==1 and y.pop()==1: WA 0.0006 0.2043 0.0517 0.0409 0.4170
max(x)==1==min(x): RE 0.0006 0.4574 0.0460 0.0917 0.5466
tuple(set(x))==(1,): WA 0.0006 0.2046 0.0410 0.0408 0.4238
not(bool(filter(lambda y: y!=1, x))): WA WA WA 0.0004 0.0004 0.0004
all(x): 0.0001 0.0001 0.0839 WA 0.0001 WA
Python 2.7.3
all(el==1 for el in x): 0.0003 0.0008 0.7175 0.0751 0.0006 0.0006
x==[1]*len(x): 0.0002 0.0003 0.0741 0.0110 0.0094 0.1015
not([1 for y in x if y!=1]): 0.0001 0.0003 0.3908 0.0948 0.0954 0.9840
set(x).issubset({1}): 0.0003 0.0005 0.2084 0.0422 0.0420 0.4198
y = set(x); len(y)==1 and y.pop()==1: WA 0.0006 0.2083 0.0421 0.0418 0.4178
max(x)==1==min(x): RE 0.0006 0.4568 0.0442 0.0866 0.4937
tuple(set(x))==(1,): WA 0.0006 0.2086 0.0424 0.0421 0.4202
not(bool(filter(lambda y: y!=1, x))): 0.0004 0.0011 0.9809 0.1936 0.1925 2.0007
all(x): 0.0001 0.0001 0.0811 WA 0.0001 WA
[PyPy 1.9.0] Python 2.7.2
all(el==1 for el in x): 0.0013 0.0093 0.4148 0.0508 0.0036 0.0038
x==[1]*len(x): 0.0006 0.0009 0.4557 0.0575 0.0177 0.1368
not([1 for y in x if y!=1]): 0.0009 0.0015 175.10 7.0742 6.4390 714.15 # No, this wasn't run 1000 times. Had to time it separately.
set(x).issubset({1}): 0.0010 0.0020 0.0657 0.0138 0.0139 0.1303
y = set(x); len(y)==1 and y.pop()==1: WA 0.0011 0.0651 0.0137 0.0137 0.1296
max(x)==1==min(x): RE 0.0011 0.5892 0.0615 0.1171 0.5994
tuple(set(x))==(1,): WA 0.0014 0.0656 0.0163 0.0142 0.1302
not(bool(filter(lambda y: y!=1, x))): 0.0030 0.0081 0.2171 0.0689 0.0680 0.7599
all(x): 0.0011 0.0044 0.0230 WA 0.0013 WA
使用了以下测试用例:
[] # True
[1]*6 # True
[1]*10000 # True
[1]*1000+[2]*1000 # False
[0]*1000+[1]*1000 # False
[random.randint(1, 2) for _ in range(20000)] # False
WA
表示解决方案提供了错误答案; RE
代表运行时错误。
所以我的结论是, Winston Ewert 的x==[1]*len(x)
solution在大多数情况下是最快的。如果你很少有所有的列表(数据是随机的,等等),或者你不想使用额外的RAM,我的解决方案会更好。如果列表很小,则差异可以忽略不计。
答案 1 :(得分:42)
更多可能的方法:
x == [1] * len(x)
list(set(x)) == [1]
tuple(set(x)) == (1,)
一些时间安排结果:
all(el==1 for el in x) [1.184262990951538, 1.1856739521026611, 1.1883699893951416]
y = set(x);len(y) == 1 and y.pop() == 1 [0.6140780448913574, 0.6152529716491699, 0.6156158447265625]
set(x) == set([1]) [0.8093318939208984, 0.8106880187988281, 0.809283971786499]
not(bool(filter(lambda y: y!=1, x))) [1.615243911743164, 1.621769905090332, 1.6134231090545654]
not any(i!=1 for i in x) [1.1321749687194824, 1.1325697898864746, 1.132157802581787]
x == [1]*len(x) [0.3790302276611328, 0.3765430450439453, 0.3812289237976074]
list(set(x)) == [1] [0.9047720432281494, 0.9006211757659912, 0.9024860858917236]
tuple(set(x)) == (1,) [0.6586658954620361, 0.6594271659851074, 0.6585478782653809]
在PyPy上因为:为什么不呢?
all(el==1 for el in x) [0.40866899490356445, 0.5661730766296387, 0.45672082901000977]
y = set(x);len(y) == 1 and y.pop() == 1 [0.6929471492767334, 0.6925959587097168, 0.6805419921875]
set(x) == set([1]) [0.956063985824585, 0.9526000022888184, 0.955935001373291]
not(bool(filter(lambda y: y!=1, x))) [0.21160888671875, 0.1965351104736328, 0.19921493530273438]
not any(i!=1 for i in x) [0.44970107078552246, 0.509315013885498, 0.4380669593811035]
x == [1]*len(x) [0.5422029495239258, 0.5407819747924805, 0.5440030097961426]
list(set(x)) == [1] [1.0170629024505615, 0.9520189762115479, 0.940842866897583]
tuple(set(x)) == (1,) [0.9174900054931641, 0.9112720489501953, 0.9102160930633545]
答案 2 :(得分:16)
除了已提供的all()
答案外,您还可以使用set()
执行此操作:
>>> x = [1, 1, 1, 1, 1, 1]
>>> y = set(x)
>>> len(y) == 1 and y.pop() == 1
True
>>> a = [1, 1, 1, 1, 0]
>>> b = set(a)
>>> len(b) == 1 and b.pop() == 1
False
<强>买者; (和赎回因子):
all()
解决方案答案 3 :(得分:10)
@ sampson-chen有一个好主意可以使用一些帮助。考虑对他的回答进行投票,并将此视为一个扩展评论。 (我不知道如何在评论中使代码看起来很好)。这是我的重写:
>>> setone = set([1])
>>> x = [1, 1, 1, 1, 1, 1]
>>> set(x) == setone
True
此代码完全与原始问题不匹配,因为它会返回False
一个空列表,这可能是好的也可能是坏的但可能并不重要。
根据社区反馈(感谢@Nabb),这是第二次重写:
>>> x = [1, 1, 1, 1, 1, 1]
>>> set(x).issubset({1})
这正确处理x是空列表的情况。
我认为这是可读的。 和变体部分写得更快(几乎快两倍)。实际上,在我的Python 2.7系统中,对于最多20个元素的列表和全部为1的列表总是更快。 (最多快3倍。)
如果列表为空,则命题“列表中的每个元素等于一”是vacuously true。
评论中的进一步讨论导致@ sampson-chen写作:
我觉得它应该是空虚的;也许这篇文章中的某个人最终会启发我们的语义。 - sampson-chen
让我们看看Python的想法:
>>> all([])
True
那么怎么样:
>>> any([])
False
那为什么这样呢?如果你没有碰到这个可能会让人感到困惑。有一种思考方式可以帮助你理解和记忆。
让我们稍微回顾一下,然后开始:
>>> sum(mylist)
Python的内置函数sum
将可迭代的项从左到右相加并返回总和。更抽象地思考,sum
通过应用加法运算符来减少迭代。
>>> sum([])
0
什么都不是0.这很直观。但是这个怎么样:
>>> product([])
好的,实际返回名称错误,因为product
不作为内置函数存在。但应该它返回什么? 0?不,empty product的值是1.这在数学上是最一致的(单击链接以获得完整的解释),因为1是乘法的identity element。 (记住sum([])
返回0,即添加的标识元素。)
理解身份元素扮演的特殊角色,并回到原来的问题:
all([])
相当于使用Boolean and
operator缩小列表。 and
的标识元素为True,因此空列表的结果为True
。
any([])
or
的标识元素为False
,与此表达式的值相同。
答案 4 :(得分:2)
这将通过列表并收集任何非1的条款。如果存在这些条款,则bool返回True并且答案为False。
not(bool(filter(lambda y: y!=1, x)))
答案 5 :(得分:1)
使用all()
的堂兄any()
的一些控制台示例:
In [4]: x = [1, 1, 1, 1, 1, 1]
In [5]: not any(i!=1 for i in x)
Out[5]: True
In [6]: x = [1, 1, 1, 1, 1, 0]
In [7]: not any(i!=1 for i in x)
Out[7]: False
答案 6 :(得分:1)
怎么样:
lo = min(L)
hi = max(L)
if (lo != 1) and (hi != 1) and (lo != hi):
print "fail"
答案 7 :(得分:1)
另一种方式是:
arr = [1,1,1,1]
len(arr) == sum(arr) #True if arr is all 1's