C #: Is there something similar to the Pdeon setdefault in the C # dictionary?

Trying to translate several methods written in Python into C #. The line looks like this:

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

What exactly does setdefault do? And is there anything similar that I can use in the C # dictionary? Rather, how can I translate this string into C #?

+4
source share
5 answers

From Python Docs :

setdefault(key[, default])

If the key is in the dictionary, return its value. If not, insert the key with the default value and return the default value. the default is None by default.

There is no direct implementation in the .NET Framework, but you can define an extension method:

 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; } } 

Using:

 string key; Dictionary<string, int> dict; dict[key] = dict.SetDefault(key, 0) + 1; 
+12
source

Edit - warning: the following only works for this particular case, not for the general case - see below.

 int value = 0; d.TryGetValue(p, out value); d[p] = value + 1; 

this is equivalent to the following Python snippet (which is better than the one you are showing):

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

setdefault is similar to get (fetching if present, otherwise using a different value) plus the side effect of injecting a key / other value pair into a dict if the key was not there; but here this side effect is useless, since you are still going to assign d[p] , so using setdefault in this case is just stupid (complicates the situation and slows down to the right goal).

In C #, TryGetValue , as the name suggests, tries to get the value corresponding to the key in its out parameter, but if the key is missing, then it ( warning: the following phrase is incorrect:) just leaves the said value on its own ( edit:) . What he actually does if the key is not present is not to "leave the value alone" (it cannot, because it has a value of out , see comments), but to set its default value for the type is here, since 0 (default value) is what we want, we are fine, but this does not make TryGetValue a general purpose replacement for Python dict.get .

TryGetValue also returns a logical result, telling you whether it managed to get the value or not, but in this case it is not needed (simply because the default behavior suits us). To create the general Python equivalent of dict.get , you need one more idiom:

 if (!TryGetValue(d, k)) { k = whatyouwant; } 

Now this idiom is really equivalent to the universal Python equivalent k = d.get(k, whatyouwant) .

+6
source

If you want the default element to have an instance of the default object, you can consider this (from 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; } 

This leads to a pretty nice syntax:

 var children = new Dictionary<string, List<Node>>(); d.SetDefault("left").Add(childNode); 
+1
source

d.setdefault (p, 0) will return the value of the record with key p, if it exists, and if not, it will set the value for key p to 0.

0
source

I know that I'm late for the party for 3 years, but an option that works and is useful:

 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; } 

That is, for value types that can be initialized without a parameter, do this.

 var lookup = new Dictionary<string, HashSet<SomeType>>(); lookup.SetDefault("kittens").Add(mySomeType); 
0
source

All Articles