How to read a python tuple using PyYAML?
<p>I have the following YAML file named <code>input.yaml</code>:</p>

<pre class="lang-yaml prettyprint-override"><code>cities:
  1: [0,0]
  2: [4,0]
  3: [0,4]
  4: [4,4]
  5: [2,2]
  6: [6,2]
highways:
  - [1,2]
  - [1,3]
  - [1,5]
  - [2,4]
  - [3,4]
  - [5,4]
start: 1
end: 4
</code></pre>

<p>I'm loading it using PyYAML and printing the result as follows:</p>

<pre class="lang-py prettyprint-override"><code>import yaml

f = open("input.yaml", "r")
data = yaml.load(f)
f.close()

print(data)
</code></pre>

<p>The result is the following data structure:</p>

<pre class="lang-py prettyprint-override"><code>{ 'cities': { 1: [0, 0]
            , 2: [4, 0]
            , 3: [0, 4]
            , 4: [4, 4]
            , 5: [2, 2]
            , 6: [6, 2]
            }
, 'highways': [ [1, 2]
              , [1, 3]
              , [1, 5]
              , [2, 4]
              , [3, 4]
              , [5, 4]
              ]
, 'start': 1
, 'end': 4
}
</code></pre>

<p>As you can see, each city and highway is represented as a list. However, I want them to be represented as a tuple. Hence, I manually convert them into tuples using comprehensions:</p>

<pre class="lang-py prettyprint-override"><code>import yaml

f = open("input.yaml", "r")
data = yaml.load(f)
f.close()

data["cities"] = {k: tuple(v) for k, v in data["cities"].items()}
data["highways"] = [tuple(v) for v in data["highways"]]

print(data)
</code></pre>

<p>However, this seems like a hack. Is there some way to instruct PyYAML to directly read them as tuples instead of lists?</p>

<p>I wouldn't call what you've done hacky for what you are trying to do. Your alternative approach from my understanding is to make use of python-specific tags in your YAML file so it is represented appropriately when loading the yaml file. However, this requires you modifying your yaml file which, if huge, is probably going to be pretty irritating and not ideal.</p>

<p>Look at the <a href="http://pyyaml.org/wiki/PythonTagScheme" rel="nofollow">PyYaml doc</a> that further illustrates this. Ultimately you want to place a <code>!!python/tuple</code> in front of your structure that you want to represented as such. To take your sample data, it would like: </p>

<p>YAML FILE:</p>

<pre><code>cities:
  1: !!python/tuple [0,0]
  2: !!python/tuple [4,0]
  3: !!python/tuple [0,4]
  4: !!python/tuple [4,4]
  5: !!python/tuple [2,2]
  6: !!python/tuple [6,2]
highways:
  - !!python/tuple [1,2]
  - !!python/tuple [1,3]
  - !!python/tuple [1,5]
  - !!python/tuple [2,4]
  - !!python/tuple [3,4]
  - !!python/tuple [5,4]
start: 1
end: 4
</code></pre>

<p>Sample code: </p>

<pre><code>import yaml

with open('y.yaml') as f:
    d = yaml.load(f.read())

print(d)
</code></pre>

<p>Which will output: </p>

<pre><code>{'cities': {1: (0, 0), 2: (4, 0), 3: (0, 4), 4: (4, 4), 5: (2, 2), 6: (6, 2)}, 'start': 1, 'end': 4, 'highways': [(1, 2), (1, 3), (1, 5), (2, 4), (3, 4), (5, 4)]}
</code></pre>

python yaml pyyaml