Skip to main content
 首页 » 编程设计

Python 根据条件插入元素

2025年05月04日20bluestorm

我正在尝试根据条件制作一个列表,其中元素可能存在也可能不存在。例如,如果为真,则列表为 [1, 2, 3],否则为 [1, 3]。目前,我可以做的是初始化列表并单独调用 .insert 或 .append 元素,或者我可以做类似 [1] 的事情+ ([2] if condition else []) + [3],但这很难看。

我想知道是否有某种语法,例如 [1, 2 if condition, 3],但我似乎找不到任何此类语法。有类似的语法吗?

编辑 我的列表不是[1, 2, 3]。我想要一个适用于任何类型对象的通用解决方案,因为我什至不使用数字(这些是 WTForms 验证器)

请您参考如下方法:

我也习惯于在 Perl 中使用如下模式来执行此操作:

my @arr = (1, (condition? (2) : ()), 3); 

在 Python 中,你可以通过一个非常接近列表 + 的解决方案来接近这个,但是使用 * 解包来避免很多其他数组:

arr = [1, *((2,) if condition else ()), 3] 

如果条件为真,可以使用生成值的助手来稍微清理一下。

T = TypeVar("T") 
 
def cond(val: T, ok: bool) -> Iterable[T]: 
    if ok: 
        yield val 
 
arr = [1, *cond(2, condition), 3] 

虽然这有一个缺点,就是不会短路,所以如果使用值的创建成本很高,您可能希望提供一个函数,而不是在条件为真时调用和返回的值。

另一种选择是在构建列表时使用标记值并对其进行过滤。可以将它与助手结合起来进行过滤。

class _Ignore: pass 
IGNORE = _Ignore() 
 
def cond_list(*elements: Union[T, _Ignore]) -> list[T]: 
    return [e for e in elements if not isinstance(e, _Ignore)] 
 
 
arr = cond_list(1, 2 if condition else IGNORE, 3) 

如果您想对生成的容器类型保持灵 active ,您可以选择返回一个可传递给容器构造函数的可迭代对象:

def cond_iter(*elements: Union[T, _Ignore]) -> Iterable[T]: 
    yield from (e for e in elements if not isinstance(e, _Ignore)) 
 
 
arr = set(cond_iter(1, 2 if condition else IGNORE, 3))