我有一个列表,它可能包含也可能不包含满足给定谓词的唯一元素。我正在寻找一个表达式,如果它存在和是唯一的,则计算为满足该谓词的项目,否则返回None
。就像
numbers = [4, 3, 9, 7, 1, 2, 8]
print(the(item for item in numbers if item > 10)) # None
print(the(item for item in numbers if item % 2 == 0)) # None
print(the(item for item in numbers if item % 7 == 0)) # 7
是否有内置的习惯用法,或者我必须编写自己的the
函数?
我不知道一个单一的表达方式,但这个简单的函数应该工作:
def the(it, cond):
l = [ i for i in it if cond(i) ]
return l[0] if len(l) == 1 else None
测试:>>> print(the(numbers,(lambda x: x > 10)))
None
>>> print(the(numbers,(lambda x: x % 7 == 0)))
7
>>> print(the(numbers,(lambda x: x % 2 == 0)))
None
您可以尝试使用islice
询问两个元素,这会更简单:
def the(it):
tmp = list(islice(it, 2))
return tmp[0] if len(tmp) == 1 else None
或循环:
def the(it):
value = None
for i, value in enumerate(it):
if i == 1:
return None
return value
或者next
的另一种用法:
def the(it):
first = next(it, None)
o = object()
if next(it, o) is o:
return first
或与你的相似:
def the(it):
first = next(it, None)
try:
next(it)
except:
return first
为了记录,我可以只写the
def the(it):
it = iter(it)
try:
value = next(it)
except StopIteration:
return None
try:
next(it)
except StopIteration:
return value
return None
这个问题应该有一个简单的解决方案:
def the(items):
return items[0] if (len(items) == 1) else None
numbers = [4, 3, 9, 7, 1, 2, 8]
print(the([item for item in numbers if item > 10])) # None
print(the([item for item in numbers if item % 2 == 0])) # None
print(the([item for item in numbers if item % 7 == 0])) # 7
您还可以应用以下格式。从代码的角度来看,它可能不会更简单,但当项数较大时,它肯定会更快。
print(the(list(filter(lambda x: x > 10, numbers)))) # None
print(the(list(filter(lambda x: x % 2 == 0, numbers)))) # None
print(the(list(filter(lambda x: x % 7 == 0, numbers)))) # 7
您可以使用以下惰性方法。从生成器表达式中获取下两项,如果来自生成器的第二项不是None
,则返回None
:
def func(lst, pred):
gen = (i for i in lst if pred(i))
v, w = next(gen, None), next(gen, None)
return v if w is None else None
print(func([4, 3, 9, 7, 1, 2, 8], lambda x: x>10))
# None
print(func([4, 3, 9, 7, 1, 2, 8], lambda x: x % 2 == 0))
# None
print(func([4, 3, 9, 7, 1, 2, 8], lambda x: x % 7 == 0))
# 7
print(func([4, 3, 9, 0, 1, 2, 8], lambda x: x % 7 == 0))
# 0