这可能是一个微不足道的问题,但我想更多地了解其他更聪明有效的解决方法。
我有一个项目列表,每个项目都有一个属性a
,其值为二进制。
a == 0
,那么我会设置一个单独的变量b = 0
。 a == 1
,那么我设置b = 1
。a == 0
和a == 1
,那么我就设置了
b = 2
。我可以使用一个集来跟踪a
值的类型,这样如果在遍历列表后集合中有两个项目,那么我可以设置b = 2
,而如果集合中只有一个项目我只检索项目(0或1)并使用它来设置b
。
有更好的方法吗?
答案 0 :(得分:26)
一次通过列表,没有构建额外的数据结构:
def zot(bs):
n, s = len(bs), sum(bs)
return 1 if n == s else 2 if s else 0
答案 1 :(得分:18)
我建议使用any
和all
。我想说这样做的好处是可读性而不是聪明或效率。例如:
>>> vals0 = [0, 0, 0, 0, 0]
>>> vals1 = [1, 1, 1, 1, 1]
>>> vals2 = [0, 1, 0, 1, 0]
>>> def category(vals):
... if all(vals):
... return 1
... elif any(vals):
... return 2
... else:
... return 0
...
>>> category(vals0)
0
>>> category(vals1)
1
>>> category(vals2)
2
如果您愿意,可以缩短一点:
>>> def category(vals):
... return 1 if all(vals) else 2 if any(vals) else 0
...
这适用于__nonzero__
(或Python 3中的__bool__
)可以解释为具有true或false值的任何内容。
答案 2 :(得分:15)
有人提到代码高尔夫,所以无法抗拒@ senderle的变种:
[0,2,1][all(vals) + any(vals)]
简短说明:它使用布尔值作为整数等价物来索引所需响应的列表。如果all
为真,那么any
也必须为真,因此它们的总和为2
。 any
本身会1
,而且匹配不会0
。这些索引从列表中返回相应的值。
如果原始要求可以修改为1
使用any
而2
使用all
,则返回{{1}的整数会更简单}
答案 3 :(得分:3)
使用字典:
zonk_values = {frozenset([0]): 0, frozenset([1]): 1, frozenset([0, 1]): 2}
def zonk(a):
return zonk_values[frozenset(a)]
这也只需要一次通过列表。
答案 4 :(得分:2)
你也可以使用套装。
s = set([i.a for i in your_list])
if len(s) == 1:
b = s.pop()
else:
b = 2
答案 5 :(得分:2)
def zot(bs):
return len(set(bs)) if sum(bs) else 0
答案 6 :(得分:1)
您可以定义两个布尔变量hasZero
和hasOne
,如果在迭代列表时满足相应的值,则将它们设置为True
。然后b = 2
hasZero and hasOne
,b = 1
hasOne
,b = 0
hasZero
。
另一种方式:您可以对列表中的所有a
值求和。如果是sumA == len(list)
,那么b = 1
,如果是sumA == 0
,那么b = 0
,如果是0 < sumA < len(list)
则b = 2
。
答案 7 :(得分:1)
短路解决方案。可能是你在Python中最有效的方式。
编辑:根据评论中的建议包括any
和all
。
EDIT2:它现在是一个单行。
b = 1 if all(A) else 2 if any(A) else 0
答案 8 :(得分:0)
这类似于senderle的建议,但是为了访问对象的a
属性而编写。
from random import randint
class Item(object):
def __init__(self, a):
self.a = a
all_zeros = [Item(0) for _ in xrange(10)]
all_ones = [Item(1) for _ in xrange(10)]
mixture = [Item(randint(0, 1)) for _ in xrange(10)]
def check(items):
if all(item.a for item in items):
return 1
if any(item.a for item in items):
return 2
else:
return 0
print 'check(all_zeros):', check(all_zeros)
print 'check(all_ones):', check(all_ones)
print 'check(mixture):', check(mixture)
答案 9 :(得分:0)
您可以使用列表iter
ators:
>>> L = [0, 0, 0, 0, 0]
>>> L1 = [1, 1, 1, 1, 1]
>>> L2 = [0, 1, 0, 1, 0]
>>> def fn(i):
... i = iter(i)
... if all(i): return 1
... return 2 if any(i) else 0
...
>>> fn(L)
0
>>> fn(L1)
1
>>> fn(L2)
2