尝试将用Python编写的some methods翻译成C#。这条线看起来像这样:
d[p] = d.setdefault(p, 0) + 1
setdefault究竟做了什么?我可以在C#字典中使用类似的东西吗?或者更确切地说,我如何将该行转换为C#?
答案 0 :(得分:13)
来自Python docs:
setdefault(key[, default])
如果键在词典中,则返回其值。如果不是,请插入值为default的值并返回default。默认默认为无。
在.NET框架中没有直接实现此功能,但您可以定义扩展方法:
public static V SetDefault<K,V>(this IDictionary<K,V> dict, K key, V @default)
{
V value;
if (!dict.TryGetValue(key, out value))
{
dict.Add(key, @default);
return @default;
}
else
{
return value;
}
}
用法:
string key;
Dictionary<string, int> dict;
dict[key] = dict.SetDefault(key, 0) + 1;
答案 1 :(得分:6)
修改 - 警告:以下内容仅适用于此特定案例,不适用于一般情况 - 请参阅下文。
int value = 0;
d.TryGetValue(p, out value);
d[p] = value + 1;
这相当于以下Python代码段(比您展示的代码段更好):
d[p] = d.get(p, 0) + 1
setdefault
类似于get
(如果存在则获取,否则使用其他值)以及如果密钥不存在则在dict中注入密钥/其他值对的副作用;但是这里的副作用是没用的,因为你无论如何都要分配d[p]
,所以在这种情况下使用setdefault
只是愚蠢(使事情变得复杂并使你慢下来没有好的目的)。
在C#中,TryGetValue
,顾名思义,尝试将与密钥对应的值放入其out
参数中,但是,如果密钥不存在,那么它
(警告:以下短语不正确:)
只留下所说的价值
(编辑)如果密钥不存在不以“单独保留值”它实际上做了什么(它不能,因为它是out
value;请参阅注释),而是将其设置为类型的默认值 - 这里,因为0(默认值)是我们想要的,我们很好,但这不会使{{1} Python的TryGetValue
。
dict.get
也返回一个布尔结果,告诉你它是否设法获取值,但在这种情况下你不需要它(只是因为默认行为恰好适合我们)。要构建Python的TryGetValue
的一般等价物,您需要另一个习语:
dict.get
现在这个成语确实是Python的if (!TryGetValue(d, k)) {
k = whatyouwant;
}
的通用等价物。
答案 2 :(得分:1)
如果您希望将项目默认为默认的对象实例,您可能需要考虑这一点(来自here)
public static TValue SetDefault<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)
{
TValue result;
if (!dictionary.TryGetValue(key, out result))
{
return dictionary[key] = (TValue)Activator.CreateInstance(typeof(TValue));
}
return result;
}
这导致了相当好的语法:
var children = new Dictionary<string, List<Node>>();
d.SetDefault(“left”).Add(childNode);
答案 3 :(得分:0)
d.setdefault(p,0)将返回带有键p的条目的值(如果它存在),如果不存在,则它将把键p的值设置为0。
答案 4 :(得分:0)
我知道我已经迟到了3年,但是一个有效的变体很有用:
public static TV SetDefault<TK, TV>(this IDictionary<TK, TV> dict, TK key) where TV: new() {
TV value;
if (!dict.TryGetValue(key, out value)) dict.Add(key, value = new TV());
return value;
}
也就是说,对于可以在没有参数的情况下初始化的值类型,请执行此操作。
var lookup = new Dictionary<string, HashSet<SomeType>>();
lookup.SetDefault("kittens").Add(mySomeType);