有时我们可能需要验证字典中是否存在密钥,并在相应的值存在时进行操作。
通常,我会这样做:
if key in my_dict:
value = my_dict[key]
# Do something
这当然是高度可读和快速的,但从逻辑的角度来看,它让我感到困扰,因为相同的动作连续两次执行。这是浪费时间。
当然,对字典中的值的访问是分摊的,通常是即时的。但是,如果情况并非如此,我们需要多次重复一次呢?
我认为第一个解决方法是使用.get()
并检查返回的值是否不是默认值。
value = my_dict.get(key, default=None)
if value is not None:
# Do Something
不幸的是,这不太实用,如果密钥存在且其对应的值恰好是None
,则可能会导致问题。
另一种方法是使用try
/ except
阻止。
try:
value = my_dict[key]
# Do something
except KeyError:
pass
然而,我非常怀疑这是最好的方法。
还有其他解决方案我不知道,还是应该继续使用传统方法?
答案 0 :(得分:5)
如果缺少值的情况非常特殊,则异常处理是恰当的:
try:
value = my_dict[key]
# Do something
except KeyError:
pass
如果要处理丢失和存在的密钥,那么您的第一个选项很有用。
if key in my_dict:
value = my_dict[key]
# Do something
get
的使用在这种特定情况下没有任何优势。相反,您必须找到一个非冲突的值来识别缺失密钥条件。
答案 1 :(得分:2)
如上所述,异常处理是最佳选择。但是,如果您想使用// serialize 2 tokens
var source = new CancellationTokenSource();
var serialized = JsonConvert.SerializeObject(source.Token);
var serialized2 = JsonConvert.SerializeObject(new CancellationTokenSource().Token);
var handle = source.Token.WaitHandle.Handle;
source.Dispose(); // releases source's handle
// spin until the OS gives us back that same handle as
// a file handle
FileStream fileStream;
while (true)
{
fileStream = new FileStream(Path.GetTempFileName(), FileMode.OpenOrCreate);
if (fileStream.Handle == handle) { break; }
}
// deserialize both tokens, thus releasing the conflicting handle
var deserialized = JsonConvert.DeserializeObject<CancellationToken>(serialized);
var deserialized2 = JsonConvert.DeserializeObject<CancellationToken>(serialized2);
GC.Collect();
GC.WaitForPendingFinalizers();
fileStream.WriteByte(1);
fileStream.Flush(); // fails with IOException "The handle is invalid"
并且get
是一个可能的值,请创建一个新对象作为&#34; not found&#34;哨兵。 (由于您刚刚创建了该对象,因此它不可能成为您None
中的有效条目。嗯,并非不可能,但您真的必须自己去将其添加到dict
。)
dict
答案 2 :(得分:1)
minqa
if语句的第二部分可能不是完全必要的,但我在我自己的代码中使用了这种格式,并且它完成了这项工作。