Python 2.7.5 collections.defaultdict 似乎仅在您将 default_factory 作为位置参数传递时才起作用——当您将其作为命名参数传递时它会中断。
如果您运行以下代码,您会看到 default_dict_success() 运行正常,但是 default_dict_failure() 抛出一个 KeyError。
from collections import defaultdict
test_data = [
('clay', 'happy'),
('jason', 'happy'),
('aj', 'sad'),
('eric', 'happy'),
('sophie', 'sad')
]
def default_dict_success():
results = defaultdict(list)
for person, mood in test_data:
results[mood].append(person)
print results
def default_dict_failure():
results = defaultdict(default_factory=list)
for person, mood in test_data:
results[mood].append(person)
print results
default_dict_success()
default_dict_failure()
输出是
# First function succeeds
defaultdict(<type 'list'>, {'sad': ['aj', 'sophie'], 'happy': ['clay', 'jason', 'eric']})
# Second function fails
Traceback (most recent call last):
File "test_default_dict.py", line 26, in <module>
default_dict_failure()
File "test_default_dict.py", line 21, in default_dict_failure
results[mood].append(person)
KeyError: 'happy'
有人知道这是怎么回事吗?
编辑:最初我以为我正在查看一些 Python 源代码,这些源代码暗示我尝试做的事情是可能的,但评论者指出我错了,因为这个对象是在 C 中实现,因此没有它的 Python 源代码。所以它并不像我想的那样相当神秘。
话虽这么说,但这是我第一次在 Python 中遇到不能同时通过名称传递的位置参数。这种事情会发生在其他地方吗?有没有一种方法可以在纯 Python(而不是 C 扩展)中实现强制执行此类行为的函数?
最佳答案
在 Modules/_collectionsmodule.c 中,defdict_init() 正在接受一个 kwargs,但除了将它传递给 PyDict_Type.tp_init() 之外没有做任何事情。
IOW,defaultdict 被记录为接受命名参数,但实现不接受,因此命名参数被传递而不是被使用。
这可能可以使用 PyArg_ParseTupleAndKeywords 来解决,而不是将其参数视为一个简单的元组。同一个模块中的双端队列类型是如何完成的示例,因为它接受几个命名参数。
我猜测,如果您在 Python 问题跟踪器中提交错误,要么更改文档以匹配实现,要么更改实现以匹配文档。
支持细节 - 当您使用 default_factory 命名参数创建 defaultdict 时,您会得到一个以 default_factory 作为键的预创建字典:
>>> import collections
>>> dd = collections.defaultdict(default_factory=int)
>>> dd
defaultdict(None, {'default_factory': <class 'int'>})
>>> dd2 = collections.defaultdict(int)
>>> dd2
defaultdict(<class 'int'>, {})
>>>
HTH
关于Python - 什么时候可以按名称传递位置参数,什么时候不能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27808449/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返
查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere