Best way to implement "enum" like python, c, java?

Since the order is important, an Elixir/erlang map is not the right structure since order is not defined

If the list is known at compile time (ie its static) then you can compile your mappings into functions. For example:

defmodule Pitch do
  @pitches [{"C", 0}, {"D", 2}, ...]

  for {note, midi_value} <- @pitches do
    def pitch(unquote(note)), do: unquote(midi_value)
    def pitch(unquote(midi_value)), do: unquote(note)
  end

end

Since functions clauses are resolved in lexical order, this implementation does rely on the keys and the values being unique.