在排序列表的字典中,例如d=={1:[1,6,16],2:[1],7:[6]}
,如何删除列表中的所有数字(以及列表最终为空的键值对),小于给定值{{1} } 有效率的?就我而言,k
会很大。
例如,如果d
,那么我们最终应该使用k = 15
。
我首先使用d == {1:[16]}
初始化字典。
我尝试使用d = defaultdict(list)
来加快速度,但我一定是犯了错误。
是否可以使用列表排序的事实来加快速度?
答案 0 :(得分:3)
>>> d = {1:[1,6,16],2:[1],7:[6]}
>>> for lst in d.values(): lst[:] = [x for x in lst if x >= 16]
...
>>> d
{1: [16], 2: [], 7: []}
>>> for k in list(d):
... if not d[k]:
... del d[k]
...
>>> d
{1: [16]}
>>> d = {1:[1,6,16],2:[1],7:[6]}
>>> tmp = [(k, [x for x in lst if x >= 16]) for k, lst in d.items()]
>>> d = {k: v for k, v in tmp if v}
>>> d
{1: [16]}
>>> d = {1:[1,6,16],2:[1],7:[6]}
>>> for k in list(d):
... d[k] = d[k][bisect.bisect_left(d[k], 16):]
... if not d[k]:
... del d[k]
...
>>> d
{1: [16]}
答案 1 :(得分:2)
你可以这样做:
from collections import defaultdict
from bisect import bisect_left
d = {1:[1,6,16],2:[1],7:[6]}
d1 = defaultdict(list)
k = 15
for key, value in d.iteritems():
temp = value[bisect_left(value, 16):]
if temp:
d1[key] = temp
print d1.items()
打印:
[(1, [16])]
答案 2 :(得分:1)
我和answer of mine有同样的感觉:我读过的所有答案在我看来都是为了创造一个新的物体。
我更喜欢对列表进行修改。
在下面的代码中,我删除了每个列表中不需要的部分(因为列表已经排序,很容易),我尊重EADP编码风格(比请求更容易要求宽恕)
d={1:[1,6,16,32,50],2:[1,5,15],7:[6,7,9],13:[10,12,23,55]}
k = 15
for ki,li in d.items():
try:
x = next(x for x in li if x>=k)
except:
del d[ki]
else:
i = li.index(x)
li[0:i] = []
print d
# {1: [16, 32, 50], 2: [15], 13: [23, 55]}
我改变了代码。这不太好,因为我不得不在d.items()
而不是d.iteritems()
进行迭代:在最后一种情况下,在迭代期间不能修改字典。
我尝试使用bisect_left()
,这确实是最快的解决方案。这是第三个代码。第二个是修正RussW的一个。第一个是我以前的代码
k = 15
te = clock()
for jj in xrange(10000):
d={1:[1,6,16,32,50],2:[1,5,15],7:[6,7,9],13:[10,12,23,55]}
for ki,li in d.items():
try:
x = next(x for x in li if x>=k)
except:
del d[ki]
else:
i = li.index(x)
li[0:i] = []
print clock() - te
print d
print '------------------------------------------'
d={1:[1,6,16,32,50],2:[1,5,15],7:[6,7,9],13:[10,12,23,55]}
te = clock()
for jj in xrange(10000):
dct={1:[1,6,16,32,50],2:[1,5,15],7:[6,7,9],13:[10,12,23,55]}
for key, lst in dct.items():
gn = None
for i, x in enumerate(lst):
if x >= k:
gn = i
break
if gn is None:
del dct[key]
else:
dct[key] = lst[gn:]
print clock() - te
print dct
print '------------------------------------------'
te = clock()
for jj in xrange(10000):
d={1:[1,6,16,32,50],2:[1,5,15],7:[6,7,9],13:[10,12,23,55]}
for ki,li in d.items():
i = bisect_left(li,15)
if i==len(li):
del d[ki]
else:
li[0:i] = []
print clock() - te
print d
结果
0.22918869577
{1: [16, 32, 50], 2: [15], 13: [23, 55]}
------------------------------------------
0.163871665254
{1: [16, 32, 50], 2: [15], 13: [23, 55]}
------------------------------------------
0.100142057161
{1: [16, 32, 50], 2: [15], 13: [23, 55]}
答案 3 :(得分:0)
>>> def sieve(dct, n):
for key, lst in dct.iteritems():
gn = None
for i, x in enumerate(lst):
if x >= n:
gn = i
break
if gn is None:
del dct[key]
else:
dct[key] = lst[gn:]
>>> d = {1:[1, 6, 16], 2:[1], 7:[6]}
>>> sieve(d, 15)
>>> d
{1: [16]}
>>>
答案 4 :(得分:0)
>>> import bisect
>>> d = {1: [1,6,16], 2: [1], 7: [6]}
>>> for k in d.keys():
... d[k] = d[k][bisect.bisect_left(d[k], 16):]
... if not d[k]:
... del d[k]
...
>>> d
{1: [16]}