一种衬里确定字典值是否全部为空列表
我有一个命令如下:
someDict = {'a':[], 'b':[]}
我想确定此字典是否具有不是空列表的任何值。如果是这样,我想返回True。如果没有,我想返回False。有什么办法可以使它成为一个班轮吗?
-
根据我的测试,以下所有内容(我的原始答案)在所有情况下均具有最佳的时间性能。有关测试信息,请参见下面的编辑。我的确承认使用生成器表达式的解决方案将大大提高内存效率,并且对于大型字典应该是首选。
编辑:这是一个老化的答案,我的测试结果可能不适用于最新版本的python。 由于生成器表达式是更“
pythonic”的方式,因此我认为它们的性能正在提高。如果您正在“热”代码路径中运行此程序,请进行自己的测试。bool([a for a in my_dict.values() if a != []])
编辑:
决定玩得开心。答案比较,不按任何特定顺序排列:
(如下所示,timeit将基于不到0.2秒的运行时间来计算循环量级)
bool([如果a == [],则为my_dict.values()中的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 my 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
any(x!= [] for my_dict.itervalues()中的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
全部(map(lambda x:x == [],my_dict.values())):
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
再次编辑-更有趣:
any()是O(1)的最佳情况(如果bool(list [0])返回True)。any()最坏的情况是“正”情况-一长串值(bool(list
[i])返回False)。看看字典变大会发生什么:
bool([如果a == [],则为my_dict.values()中的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 my 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
但这还不够-最坏的“假”情况怎么办?
bool([如果a == [],则为my_dict.values()中的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 my 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