我有一个列表,可能包含也可能不包含满足给定谓词的唯一元素。我正在寻找一个表达式,如果它存在且是唯一的,则计算满足该谓词的项目,否则返回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
函数?
答案 0 :(得分:4)
我不知道单一的表达方式,但这个简单的功能应该有效:
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
答案 1 :(得分:1)
您可以尝试使用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
答案 2 :(得分:0)
为了记录,我可以将the
写为
def the(it):
it = iter(it)
try:
value = next(it)
except StopIteration:
return None
try:
next(it)
except StopIteration:
return value
return None
答案 3 :(得分:0)
您可以使用以下惰性方法。从生成器表达式中获取接下来的两个项目,如果生成器中的第二个项目不是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
答案 4 :(得分:0)
这应该是解决此问题的简单方法:
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