我有一个字典,如下所示:
someDict = {'a':[], 'b':[]}
我想确定这个字典是否有任何不是空列表的值。如果有,我想返回True。如果没有,则返回False。有没有办法将其变成一个单行代码?
我想确定这个字典是否有任何不是空列表的值。如果有,我想返回True。如果没有,则返回False。有没有办法将其变成一个单行代码?
我有一个字典,如下所示:
someDict = {'a':[], 'b':[]}
我想确定这个字典是否有任何不是空列表的值。如果有,我想返回True。如果没有,则返回False。有没有办法将其变成一个单行代码?
我想确定这个字典是否有任何不是空列表的值。如果有,我想返回True。如果没有,则返回False。有没有办法将其变成一个单行代码?
根据我的测试结果,在所有场景下,以下一行代码(即我的原始答案)具有最佳的时间性能。请参见下面的编辑以获取测试信息。我承认,使用生成器表达式的解决方案在内存效率上会更好,并且应该优先考虑用于大型字典。
编辑:这是一个过时的答案,我的测试结果可能不适用于最新版本的Python。由于生成器表达式是更“Pythonic”的方式,我想它们的性能正在改善。如果您在“热”代码路径中运行此代码,请进行自己的测试。
bool([a for a in my_dict.values() if a != []])
编辑:
决定有些乐趣。以下是答案比较,没有特定顺序:
(如下所示,timeit将根据少于0.2秒的运行时间计算循环顺序)
bool([a for a in my_dict.values() if a != []]):
python -mtimeit -s"my_dict={'a':[],'b':[]}" "bool([a for a in my_dict.values() if a != []])"
1000000 loops, best of 3: 0.875 usec per loop
any([my_dict[i] != [] for i in my_dict]) :
python -mtimeit -s"my_dict={'a':[],'b':[]}" "any([my_dict[i] != [] for i in my_dict])"
1000000 loops, best of 3: 0.821 usec per loop
在我的字典中任意一个值不为空列表(x != [])时:
python -mtimeit -s"my_dict={'a':[],'b':[]}" "any(x != [] for x in my_dict.itervalues())"
1000000 loops, best of 3: 1.03 usec per loop
检查my_dict字典的所有值是否为空列表,返回布尔值。
python -mtimeit -s"my_dict={'a':[],'b':[]}" "all(map(lambda x: x == [], my_dict.values()))"
1000000 loops, best of 3: 1.47 usec per loop
filter(lambda x: x != [], my_dict.values()):
python -mtimeit -s"my_dict={'a':[],'b':[]}" "filter(lambda x: x != [], my_dict.values())"
1000000 loops, best of 3: 1.19 usec per loop
再次编辑 - 更有趣:
如果bool(list[0])返回True,any()的最佳情况是O(1)。any()的最坏情况是“正面”场景 - 一个长列表的值,其中bool(list[i])返回False。
看看字典变大时会发生什么:
bool([a for a in my_dict.values() if a != []]) :
#n=1000
python -mtimeit -s"my_dict=dict(zip(range(1000),[[]]*1000))" "bool([a for a in my_dict.values() if a != []])"
10000 loops, best of 3: 126 usec per loop
#n=100000
python -mtimeit -s"my_dict=dict(zip(range(100000),[[]]*100000))" "bool([a for a in my_dict.values() if a != []])"
100 loops, best of 3: 14.2 msec per loop
any([my_dict[i] != [] for i in my_dict]):
#n=1000
python -mtimeit -s"my_dict=dict(zip(range(1000),[[]]*1000))" "any([my_dict[i] != [] for i in my_dict])"
10000 loops, best of 3: 198 usec per loop
#n=100000
python -mtimeit -s"my_dict=dict(zip(range(100000),[[]]*100000))" "any([my_dict[i] != [] for i in my_dict])"
10 loops, best of 3: 21.1 msec per loop
但这还不够-如果是最坏的“False”情况呢?
bool([a for a in my_dict.values() if a != []]) :
python -mtimeit -s"my_dict=dict(zip(range(1000),[0]*1000))" "bool([a for a in my_dict.values() if a != []])"
10000 loops, best of 3: 198 usec per loop
any([my_dict[i] != [] for i in my_dict]) :
python -mtimeit -s"my_dict=dict(zip(range(1000),[0]*1000))" "any([my_dict[i] != [] for i in my_dict])"
1000 loops, best of 3: 265 usec per loop
非假值或非空列表:
非假值:
any(someDict.values())
非空列表:
any(a != [] for a in someDict.values())
或者any(map(lambda x: x != [], someDict.values()))
或者,如果您接受一个假值作为返回值:
filter(lambda x: x != [], someDict.values())
返回一个非空列表的列表,如果它们全部为空列表,则返回空列表 :)确切地说:
any(x != [] for x in someDict.itervalues())
all([d[i] == [] for i in d])
编辑:糟糕,我想我把你搞反了。让我们对德摩根定理进行转化。
any([d[i] != [] for i in d])
第二种方法在任何情况下都具有比第一种更短的路线优势。
>>> someDict = {'a':[], 'b':[]}
>>> all(map(lambda x: x == [], someDict.values()))
True
列表解析
替换为生成器表达式
。 - user395760dict(('a'*i, [i]) for i in range(10000))
进行基准测试)。你还可以省下两个括号 ;) - user395760len(filter(lambda x: x!=[], someDict.values())) != 0