Python习语返回唯一的元素或None

时间:2016-11-14 09:57:42

标签: python idioms

我有一个列表,可能包含也可能不包含满足给定谓词的唯一元素。我正在寻找一个表达式,如果它存在是唯一的,则计算满足该谓词的项目,否则返回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函数?

5 个答案:

答案 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