当前位置: 首页 > 面试题库 >

python dict:获取vs setdefault

拓拔浩阔
2023-03-14
问题内容

以下两个表达式似乎与我等效。哪一个更好?

data = [('a', 1), ('b', 1), ('b', 2)]

d1 = {}
d2 = {}

for key, val in data:
    # variant 1)
    d1[key] = d1.get(key, []) + [val]
    # variant 2)
    d2.setdefault(key, []).append(val)

结果是相同的,但是哪个版本更好或更确切地说是pythonic?

我个人觉得版本2更难理解,对我而言setdefault非常难以掌握。如果我理解正确,它将在字典中查找“键”的值(如果不可用),在字典中输入“
[]”,返回对该值或“ []”的引用,并在该值后附加“ val”参考。虽然肯定很平滑,但至少(至少对我而言)不是直观的。

在我看来,版本1更容易理解(如果可用,请获取“ key”的值,否则请获取“ []”,然后加入由[val]组成的列表并将结果放入“ key”
)。但是,虽然更直观易懂,但我担心此版本的性能会下降,所有这些列表都会创建。另一个缺点是“
d1”在表达式中出现两次,这很容易出错。可能有一个使用get的更好的实现,但是目前我无法理解。

我的猜测是,尽管经验不足的人更难以掌握版本2,但它会更快,因此更可取。意见?


问题答案:

你的两个例子做同样的事情,但并不意味着getsetdefault做。

两者之间的区别基本上是手动设置d[key]为每次指向列表,而不是仅在未设置时才setdefault自动设置d[key]为列表。

我使这两种方法尽可能相似

from timeit import timeit

print timeit("c = d.get(0, []); c.extend([1]); d[0] = c", "d = {1: []}", number = 1000000)
print timeit("c = d.get(1, []); c.extend([1]); d[0] = c", "d = {1: []}", number = 1000000)
print timeit("d.setdefault(0, []).extend([1])", "d = {1: []}", number = 1000000)
print timeit("d.setdefault(1, []).extend([1])", "d = {1: []}", number = 1000000)

并得到

0.794723378711
0.811882272256
0.724429205999
0.722129751973

因此setdefaultget为此目的快10%。

get方法可以使您做的事 少于
使用setdefaultKeyError即使您不想设置密钥,也可以使用它来避免在密钥不存在时得到提示(如果那会经常发生)。

请参阅“ setdefault”的dict方法的用例,并且dict.get()方法返回一个指针,以获取有关这两种方法的更多信息。

关于主题的setdefault结论是,大多数情况下,您想使用defaultdict。关于该线程的get结论是它很慢,通常最好(在速度方面)使用defaultdict或处理错误(取决于字典的大小和您的用例)进行双重查找。



 类似资料:
  • 我们使用nextjs/reactjs作为FE,并且我们有一个server.js文件,它允许我们在上传映像,但是由于某种原因,每当我们运行服务器时,都会出现错误 下面是我们在server.js上的代码 这些是我们package.json中包含的脚本 希望得到一些答案和建议。这些代码在本地运行,没有任何问题

  • 英文原文: http://emberjs.com/guides/getting-ember/index/ Ember构建 Ember的发布管理团队针对Ember和Ember Data维护了不同的发布方法。 频道 最新的Ember和Ember Data的 Release,Beta 和 Canary 构建可以在这里找到。每一个频道都提供了一个开发版、最小化版和生产版。更多关于不同频道的信息可以查看博客

  • 获取资讯列表 获取置顶资讯列表 获取资讯详情 获取一条资讯的相关资讯 获取资讯列表 GET /news 传入参数 名称 说明 limit 数据返回条数 默认为20 after 数据翻页标识 key 搜索关键字 cate_id 分类id recommend 推荐筛选 =1为筛选推荐资讯列表 id 需要按照 ID 获取的资讯 ID,多个使用半角 , 进行分割 Response Status: 200

  • 我刚到Angular 2还在学习,我正在尝试用get调用击一个URL,但get似乎不通过,即使在浏览器的网络中,我也找不到被调用的get URL。 程序将转到方法控制台,在get调用的上下记录日志,但不记录get调用的日志 我的服务方式

  • 我有一个使用redux的应用程序 我也曾在本地获取数据。 在我的反应组件中,我使用来获取数据。但我什么也没得到。 如何在我的组件中获取数据? 演示:https://codesandbox.io/s/nervous-rosalind-lp16j?file=/src/App.js:242-328

  • 我在生产环境中遇到以下错误 DEBUG org.apache.camel.processor.DefaultErrorHandler - exchangeId 的传递失败:ID-*-56874-1372457272212-0-1。传递尝试时:0 捕获:org.apache.camel.CamelExecutionException:在交换执行期间发生异常:Exchange DEBUG org.ap

  • 1.5. 获取URL 对于很多现代应用来说,访问互联网上的信息和访问本地文件系统一样重要。Go语言在net这个强大package的帮助下提供了一系列的package来做这件事情,使用这些包可以更简单地用网络收发信息,还可以建立更底层的网络连接,编写服务器程序。在这些情景下,Go语言原生的并发特性(在第八章中会介绍)显得尤其好用。 为了最简单地展示基于HTTP获取信息的方式,下面给出一个示例程序fe