Differences Between Ways of Initializing a Dictionary

Proper way to initialize a C# dictionary with values

I can't reproduce this issue in a simple .NET 4.0 console application:

static class Program
{
static void Main(string[] args)
{
var myDict = new Dictionary<string, string>
{
{ "key1", "value1" },
{ "key2", "value2" }
};

Console.ReadKey();
}
}

Can you try to reproduce it in a simple Console application and go from there? It seems likely that you're targeting .NET 2.0 (which doesn't support it) or client profile framework, rather than a version of .NET that supports initialization syntax.

Initializing a dictionary in python with a key value and no corresponding values

You could initialize them to None.

Dictionary initializer has different behavior and raises run-time exception when used in combination of array initializer

Let me try to answer all of your questions:


  1. Is this expected behavior and is it documented somewhere?

Yes, it is documented in the C# 6.0 Language Specification under sections §7.6.11.2 Object initializers and §7.6.11.3 Collection initializers.

The syntax

var a =
new Test
{
[1] = "foo"
[2] = "bar"
};

was actually newly introduced in C# 6.0 as an extension of the previous object initialization syntax to indexers. An object initializer used together with new (see object creation expression, §7.6.11) always translates to object instantiation and member access of the corresponding object (using a temporary variable), in this case:

var _a = new Test();
_a[1] = "foo";
_a[2] = "bar";
var a = _a;

The collection initializer goes similar besides that each element of the initializer is passed as an argument to the Add method of the newly created collection:

var list = new List<int> {1, 2};

becomes

var _list = new List<int>();
_list.Add(1);
_list.Add(2);
var list = _list;

An object initializer can also contain other object or collection initializers. The specification states for the case of collection initializers:

A member initializer that specifies a collection initializer after the
equals sign is an initialization of an embedded collection. Instead of
assigning a new collection to the target field, property or indexer,
the elements given in the initializer are added to the collection
referenced by the target.

So a sole collection initalizer used within an object initializer will not attempt to create a new collection instance. It will only try to add the elements to an exisiting collection, i.e. a collection that was already instantiated in the constructor of the parent object.

Writing

[1] = new List<string> { "str1", "str2", "str3" }

is actually a totally different case because this is an object creation expression which only contains an collection initializer, but isn't one.



  1. Why is the syntax above allowed but the following
    syntax is not?

    List<string> list = { "test" };

Now, this is not a collection initializer anymore. A collection initalizer can only occur inside an object initializer or in an object creation expression. A sole { obj1, obj2 } next to an assignment is actually an array initializer (§12.6). The code does not compile since you can't assign an array to a List<string>.



  1. Why is the following syntax not allowed then?

    var dict = new Dictionary<int, string[]> 
    {
    [1] = { "test1", "test2", "test3" },
    [2] = { "test4", "test5", "test6" }
    };

It is not allowed because collection initalizers are only allowed to initialize collections, not array types (since only collections have an Add method).

Different ways to initialize a dictionary in Swift?

All you're doing is noticing that you can:

  • Use explicit variable typing, or let Swift infer the type of the variable based on the value assigned to it.

  • Use the formal specified generic struct notation Dictionary<String,Double>, or use the built-in "syntactic sugar" for describing a dictionary type [String:Double].

Two times two is four.

And then there are in fact some possibilities you've omitted; for example, you could say

var dict5 : [String:Double] = [String:Double]()

And of course in real life you are liable to do none of these things, but just assign an actual dictionary to your variable:

var dict6 = ["howdy":1.0]

Initializing Python dictionary using dict() vs {}

There is no difference between dict_object = dict() and dict_object = {}

The problem here is [{}] * 2 will generate a list with 2 elements which are reference to a single object. [{} for x in range(2)] will generate a list with two elements which are reference two distinct objects.

Replacing {} with dict() will get the same result.

What's the difference between dict() and {}?

>>> def f():
... return {'a' : 1, 'b' : 2}
...
>>> def g():
... return dict(a=1, b=2)
...
>>> g()
{'a': 1, 'b': 2}
>>> f()
{'a': 1, 'b': 2}
>>> import dis
>>> dis.dis(f)
2 0 BUILD_MAP 0
3 DUP_TOP
4 LOAD_CONST 1 ('a')
7 LOAD_CONST 2 (1)
10 ROT_THREE
11 STORE_SUBSCR
12 DUP_TOP
13 LOAD_CONST 3 ('b')
16 LOAD_CONST 4 (2)
19 ROT_THREE
20 STORE_SUBSCR
21 RETURN_VALUE
>>> dis.dis(g)
2 0 LOAD_GLOBAL 0 (dict)
3 LOAD_CONST 1 ('a')
6 LOAD_CONST 2 (1)
9 LOAD_CONST 3 ('b')
12 LOAD_CONST 4 (2)
15 CALL_FUNCTION 512
18 RETURN_VALUE

dict() is apparently some C built-in. A really smart or dedicated person (not me) could look at the interpreter source and tell you more. I just wanted to show off dis.dis. :)

Difference between dict.clear() and assigning {} in Python

If you have another variable also referring to the same dictionary, there is a big difference:

>>> d = {"stuff": "things"}
>>> d2 = d
>>> d = {}
>>> d2
{'stuff': 'things'}
>>> d = {"stuff": "things"}
>>> d2 = d
>>> d.clear()
>>> d2
{}

This is because assigning d = {} creates a new, empty dictionary and assigns it to the d variable. This leaves d2 pointing at the old dictionary with items still in it. However, d.clear() clears the same dictionary that d and d2 both point at.

Different ways to declare a dictionary in Swift?

They both do the same thing to declare and initialize an empty dictionary of that key and value type.

Apple documents the first way in their Swift Guide. (Scroll down to Dictionaries section).

The second way you show is simply more formal, which may help those new to Swift who don’t know the dictionary shorthand/literal syntax.

The

C# 6.0's new Dictionary Initializer - Clarification

The main advantage here with a dictionary is consistency. With a dictionary, initialization did not look the same as usage.

For example, you could do:

var dict = new Dictionary<int,string>();
dict[3] = "foo";
dict[42] = "bar";

But using initialization syntax, you had to use braces:

var dict = new Dictionary<int,string>
{
{3, "foo"},
{42, "bar"}
};

The new C# 6 index initialization syntax makes initialization syntax more consistent with index usage:

var dict = new Dictionary<int,string>
{
[3] = "foo",
[42] = "bar"
};

However, a bigger advantage is that this syntax also provides the benefit of allowing you to initialize other types. Any type with an indexer will allow initialization via this syntax, where the old collection initializers only works with types that implement IEnumerable<T> and have an Add method. That happened to work with a Dictionary<TKey,TValue>, but that doesn't mean that it worked with any index based type.



Related Topics



Leave a reply



Submit