【问题标题】:Best way to check if an item is present in a list of lists? [duplicate]检查列表列表中是否存在项目的最佳方法? [复制]
【发布时间】:2015-01-10 05:07:19
【问题描述】:

我有这样的示例列表:

example_list = [['aaa'], ['fff', 'gg'], ['ff'], ['', 'gg']]

现在,我检查它是否有这样的空字符串:

has_empty = False;
for list1 in example_list:
    for val1 in list1:
        if val1 == '':
            has_empty = True

print(has_empty)

这工作正常,因为它打印 True,但是寻找更多 pythonik 方法?

【问题讨论】:

  • 说实话,这感觉更像是一个代码审查问题,但我不太确定。它如此短的代码片段被“审查”。

标签: python list python-3.x


【解决方案1】:

你可以使用itertools.chain.from_iterable:

>>> from itertools import chain
>>> example_list = [['aaa'], ['fff', 'gg'], ['ff'], ['', 'gg']]
>>> '' in chain.from_iterable(example_list)
True

如果内部列表更大(超过 100 个项目),那么使用 any 和生成器将比上面的示例更快,因为使用 Python for 循环的速度损失会被快速补偿in-操作:

>>> any('' in x for x in example_list)
True

时间比较:

>>> example_list = [['aaa']*1000, ['fff', 'gg']*1000, ['gg']*1000]*10000 + [['']*1000]
>>> %timeit '' in chain.from_iterable(example_list)
1 loops, best of 3: 706 ms per loop
>>> %timeit any('' in x for x in example_list)
1 loops, best of 3: 417 ms per loop

# With smaller inner lists for-loop makes `any()` version little slow

>>> example_list = [['aaa'], ['fff', 'gg'], ['gg', 'kk']]*10000 + [['']]
>>> %timeit '' in chain.from_iterable(example_list)
100 loops, best of 3: 2 ms per loop
>>> %timeit any('' in x for x in example_list)
100 loops, best of 3: 2.65 ms per loop

【讨论】:

    【解决方案2】:

    您可以使用anymapchain 的组合:

    In [19]: example_list = [['aaa'], ['fff', 'gg'], ['ff'], ['', 'gg']]
    
    In [20]: import operator, itertools
    
    In [21]: any(map(operator.not_, itertools.chain(*example_list)))
    Out[21]: True
    
    In [22]: example_list = [['aaa'], ['fff', 'gg'], ['ff'], ['not empty', 'gg']]
    
    In [23]: any(map(operator.not_, itertools.chain(*example_list)))
    Out[23]: False
    

    【讨论】:

    • 这将返回 True 以获得任何虚假值。
    • @AshwiniChaudhary 对于字符串,据我所知,只有空字符串才会为假。
    【解决方案3】:

    只需将整个列表转换为字符串并检查是否存在空字符串,即其中的''""

    >>> example_list = [['aaa'], ['fff', 'gg'], ['ff'], ['', 'gg']]
    >>> any(empty in str(example_list) for empty in ("''", '""'))
    True
    >>> example_list = [['aaa'], ['fff', 'gg'], ['ff'], [ 'gg', '\'']]
    >>> any(empty in str(example_list) for empty in ("''", '""'))
    False
    

    请注意,这不适用于将空字符串作为字符串本身的一部分的列表 - 例如 'hello "" world'

    另一种方法是展平 dict 并检查其中是否存在空字符串

    >>> example_list = [['aaa'], ['fff', 'gg'], ['ff'], ['gg', 'hello "" world']]
    >>> '' in [item for sublist in example_list for item in sublist]
    False
    >>> example_list = [['aaa'], ['fff', 'gg'], ['ff'], ['', 'gg', 'hello "" world']]
    >>> '' in [item for sublist in example_list for item in sublist]
    True
    

    【讨论】:

    • 有趣。如果子列表包含'hello "" world' 项怎么办?
    • @alecxe 还有另一种方法 - 展平字典,然后检查空字符串。现在在我的答案中编辑:)
    • 对于更大的列表 better use a generator expression 而不是列表理解,因为它会短路。
    • @AshwiniChaudhary 感谢优化技巧 :)
    【解决方案4】:

    使用maplambda

    >>> def check_empty(l):
    ...     k=map(lambda x: '' in x and True,l)
    ...     for x in k:
    ...         if x==True:
    ...             return True
    ...     return False
    ... 
    >>> check_empty(example_list)
    False
    >>> example_list
    [['aaa'], ['fff', 'gg'], ['ff'], ['gg', 'hello "" world']]
    >>> example_list = [['aaa'], ['fff', 'gg',''], ['ff'], ['gg', 'hello "" world']]
    >>> check_empty(example_list)
    True
    

    【讨论】:

    • 记录一下,这基本上是any()的实现。所以相当于简单的做any('' in x for x in l)
    【解决方案5】:
    example_list = [['aaa'], ['fff', 'gg'], ['ff'], ['', 'gg']]
    
    has_empty = False
    
    for list in example_list:
    
        if '' in list:
            has_empty = True
    print(has_empty)
    

    【讨论】:

      猜你喜欢
      • 2010-10-01
      • 2017-05-11
      • 1970-01-01
      • 1970-01-01
      • 2018-11-03
      • 1970-01-01
      • 2017-08-23
      • 2020-11-08
      • 1970-01-01
      相关资源
      最近更新 更多