6

在列表字典中删除每个列表的最后一个元素的更pythonic或更有效的方法是什么?

例如,采取这个:

listDict = {'tom': [-2,10,2,-8], 'sam': [-9,-10,-10,-7]}

并将其转换为:

listDict = {'tom': [-2,10,2], 'sam': [-9,-10,-10]}

这就是我目前正在做的事情:

new = {}
for t,item in listDict.iteritems():
    new[t] = [item[0], item[1], item[2]]
listDict= new
4

5 回答 5

8

我会使用字典理解:

new_dict = {key: value[:-1] for key, value in listDict.items()}

对于较旧的 Python 版本,您必须使用dict()构造函数:

new_dict = dict((key, value[:-1]) for key, value in listDict.items())
于 2012-08-11T05:12:09.017 回答
8

与此解决方案相比,随着列表长度的增加,Blender 的答案变得非常低效:

for k, v in listDict.items():
    v.pop()

对于您的示例listDict,差异不大,只有 27%。但是使用具有 100 个键和长度从 50 到 100 的列表并弹出 50 个的 dict,dict 理解方法花费的时间超过 12 倍。这是因为此解决方案会修改现有列表,而不是每次都创建每个列表的副本。

恐怕没有这样的单行版本,除非你在作弊。我之所以提到这一点,是为了防止某些 dofus 不得不在评论中指出这一点。不要将 dict/list 理解用于副作用。

当然,您可以按如下方式在一行中执行此操作,但PEP8说“而不是”:

for k, v in listDict.items(): v.pop()
于 2012-08-11T05:38:08.093 回答
2

如果您想就地修改,则此替代方法不需要创建新字典或任何其他重新分配。

listDict = {'tom': [-2,10,2,-8], 'sam': [-9,-10,-10,-7]}
for i in listDict.values():
    i.pop()

它不需要创建新列表。记住列表是可变的。

如果您确实想要新的字典和列表,那么之前的响应会更好。

于 2012-08-11T05:43:59.757 回答
1

只是为了保持分数:

def f1():
    listDict = {'tom': [-2,10,2,-8], 'sam': [-9,-10,-10,-7]}
    return {key: value[:-1] for key, value in listDict.items()}

def f2():
    listDict = {'tom': [-2,10,2,-8], 'sam': [-9,-10,-10,-7]}
    for k, v in listDict.items():
        v.pop()    

    return listDict    


cmpthese.cmpthese([f1,f2])       

印刷:

   rate/sec    f1     f2
f1  571,487    -- -23.5%
f2  746,966 30.7%     --
于 2012-08-11T05:54:35.313 回答
0

如果您能够使用pandas,请给出dict

listDict = {'tom': [-2,10,2,-8], 'sam': [-9,-10,-10,-7]}

像这样删除最后一个元素:

import pandas 
df = pandas.DataFrame(data=listDict)
new = df[:-1]
print(new)

产生:

   tom  sam
0   -2   -9
1   10  -10
2    2  -10

如果你想要它作为dict然后:

print(new.to_dict('list'))

产生:

{'tom': [-2, 10, 2], 'sam': [-9, -10, -10]}
于 2021-04-02T14:54:22.630 回答