Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# way to mimic Python Dictionary Syntax

Is there a good way in C# to mimic the following python syntax:

mydict = {}
mydict["bc"] = {}
mydict["bc"]["de"] = "123";  # <-- This line
mydict["te"] = "5";          # <-- While also allowing this line

In other words, I'd like something with [] style access that can return either another dictionary or a string type, depending on how it has been set.

I've been trying to work this out with a custom class but can't seem to succeed. Any ideas?

Thanks!

Edit: I'm being evil, I know. Jared Par's solution is great . . . for a 2-level dictionary of this form. However, I am also curious about further levels . . . for instance,

mydict["bc"]["df"]["ic"] = "32";

And so on. Any ideas about that?

Edit 3:

Here is the final class I ended up using:

class PythonDict {
    /* Public properties and conversions */
    public PythonDict this[String index] {
        get {
            return this.dict_[index];
        }
        set {
            this.dict_[index] = value;
        }
    }

    public static implicit operator PythonDict(String value) {
        return new PythonDict(value);
    }

    public static implicit operator String(PythonDict value) {
        return value.str_;
    }

    /* Public methods */
    public PythonDict() {
        this.dict_ = new Dictionary<String, PythonDict>();
    }

    public PythonDict(String value) {
        this.str_ = value;
    }

    public bool isString() {
        return (this.str_ != null);
    }

    /* Private fields */
    Dictionary<String, PythonDict> dict_ = null;
    String str_ = null;
}

This class works for infinite levels, and can be read from without explicit conversion (dangerous, maybe, but hey).

Usage like so:

        PythonDict s = new PythonDict();
        s["Hello"] = new PythonDict();
        s["Hello"]["32"] = "hey there";
        s["Hello"]["34"] = new PythonDict();
        s["Hello"]["34"]["Section"] = "Your face";
        String result = s["Hello"]["34"]["Section"];
        s["Hi there"] = "hey";

Thank you very much Jared Par!

like image 431
Walt W Avatar asked Sep 04 '09 20:09

Walt W


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr. Stroustroupe.

What is C in C language?

What is C? C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.

Is C language easy?

C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.


2 Answers

You can achieve this by having the class, lets call it PythonDictionary, which is returned from mydict["bc"] have the following members.

  • A indexer property to allow for the ["de"] access
  • A implicit conversion from string to PythonDictionary

That should allow both cases to compile just fine.

For example

public class PythonDictionary {
    public string this[string index] {
        get { ... }
        set { ... }
    }
    public static implicit operator PythonDictionary(string value) {
        ...
    }
}

public void Example() {
    Dictionary<string, PythonDictionary> map = new Dictionary<string, PythonDictionary>();
    map["42"]["de"] = "foo";
    map["42"] = "bar";
}
like image 125
JaredPar Avatar answered Oct 11 '22 13:10

JaredPar


Thanks for posting this question and resolution. Converted to VB.NET:

Public Class PythonDict
    ' Public properties and conversions
    Default Public Property Item(ByVal index As String) As PythonDict
        Get
            Return Me.dict_(index)
        End Get

       Set(value As PythonDict)
            Me.dict_(index) = value
       End Set
    End Property

    Public Shared Narrowing Operator CType(value As String) As PythonDict
       Return New PythonDict(value)
    End Operator

    Public Shared Widening Operator CType(value As PythonDict) As String
       Return value.str_
    End Operator

    ' Public methods
    Public Sub New()
       Me.dict_ = New Dictionary(Of String, PythonDict)()
    End Sub

    Public Sub New(value As String)
       Me.str_ = value
    End Sub

    Public Function isString() As Boolean
       Return (Me.str_ IsNot Nothing)
    End Function

    ' Private fields
    Private dict_ As Dictionary(Of String, PythonDict) = Nothing
    Private str_ As String = Nothing
End Class

Usage:

Dim s As PythonDict = New PythonDict()
s("Hello") = New PythonDict()
s("Hello")("32") = "hey there"
s("Hello")("34") = New PythonDict()
s("Hello")("34")("Section") = "Your face"
Dim result As String = s("Hello")("34")("Section")
s("Hi there") = "hey"
like image 28
jmjohnson85 Avatar answered Oct 11 '22 14:10

jmjohnson85