C#:C#中的字典是否与Python setdefault类似?

时间:2009-10-03 18:10:30

标签: c# python dictionary

尝试将用Python编写的some methods翻译成C#。这条线看起来像这样:

d[p] = d.setdefault(p, 0) + 1

setdefault究竟做了什么?我可以在C#字典中使用类似的东西吗?或者更确切地说,我如何将该行转换为C#?

5 个答案:

答案 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);
相关问题