словарь вставьте значение по умолчанию, если оно пустое - PullRequest
0 голосов
/ 03 октября 2018

Я создаю словарь из XML-файла следующим образом:

for edge in root.findall('n:graph/n:edge', ns):
        source = edge.get('source')
        target = edge.get('target')
        edges[(source, target)] = tuple([data.text for data in edge if \
        (data.get('key') == keys[0] or data.get('key') == keys[1])])

, который дает мне вывод, подобный этому:

{('4893468839', '977369380 '): (' name ',' length ') ...}

Есть ли способ добавить текст по умолчанию «noName», когда значения для поля name пусто?Все ключи имеют значение длины, но не все из них имеют имя, поэтому я хочу избежать вывода, например:

{('4893468839', '977369380'): ('длина',) ...}

Чтобы получить что-то подобное в этом случае:

{('4893468839', '977369380'): ('noName', 'length') ...}

Более подробная информация:

from lxml import etree
    class graph():
        _path = ""
    def _readFile(self):
            data = etree.parse(self._path)
            root = data.getroot()
    for edge in root.findall('n:graph/n:edge', ns):
                source = edge.get('source')
                target = edge.get('target')
                edges[(source, target)] = tuple([data.text for data in edge if data.get('key') in keys[:2]])

Учитывая фрагмент XML, подобный следующему:

<key attr.name="ref" attr.type="string" for="edge" id="d14" />
<key attr.name="name" attr.type="string" for="edge" id="d13" />
<key attr.name="geometry" attr.type="string" for="edge" id="d12" />
<key attr.name="length" attr.type="string" for="edge" id="d11" />
<key attr.name="oneway" attr.type="string" for="edge" id="d10" />
<key attr.name="highway" attr.type="string" for="edge" id="d9" />
<key attr.name="bridge" attr.type="string" for="edge" id="d8" />
<key attr.name="osmid" attr.type="string" for="edge" id="d7" />

<edge id="0" source="4331489627" target="4331489577">
  <data key="d7">435211336</data>
  <data key="d13">Calle Carretera</data>
  <data key="d9">residential</data>
  <data key="d10">False</data>
  <data key="d11">52.45</data>
  <data key="d12">LINESTRING (-4.8413613 39.4799045, -4.8414814 39.4798489, -4.8419449 39.4797838)</data>
</edge>

Будет генерировать следующеевыводим в порядке с:

{('4331489627', '4331489577'): ('Calle Carretera', '52.45')}

Но, например, естьнекоторые ребра, затуманивание имени или ключевой тег d13, как этот:

<edge id="0" source="982621562" target="946409159">
      <data key="d7">483537143</data>
      <data key="d14">CM-4106</data>
      <data key="d9">secondary</data>
      <data key="d10">False</data>
      <data key="d11">104.66499999999999</data>
      <data key="d12">LINESTRING (-4.8366071 39.4783468, -4.8368979 39.4789602, -4.8371678 39.4791592)</data>
    </edge>

В этих случаях я получаю этот вывод, так как текст тега не найден:

{('982621562', '946409159'): ('52.45',)}

И, если возможно, хотелось бы получить что-то вроде:

{('982621562', '946409159'): ('noName', '52.45')}

1 Ответ

0 голосов
/ 04 октября 2018

На основании вышеизложенного я собрал пример, который на самом деле работает:

from lxml import etree

root = etree.fromstring("""
<xml><graph>
<key attr.name="ref" attr.type="string" for="edge" id="d14" />
<key attr.name="name" attr.type="string" for="edge" id="d13" />
<key attr.name="geometry" attr.type="string" for="edge" id="d12" />
<key attr.name="length" attr.type="string" for="edge" id="d11" />
<key attr.name="oneway" attr.type="string" for="edge" id="d10" />
<key attr.name="highway" attr.type="string" for="edge" id="d9" />
<key attr.name="bridge" attr.type="string" for="edge" id="d8" />
<key attr.name="osmid" attr.type="string" for="edge" id="d7" />
<edge id="0" source="4331489627" target="4331489577">
  <data key="d7">435211336</data>
  <data key="d13">Calle Carretera</data>
  <data key="d9">residential</data>
  <data key="d10">False</data>
  <data key="d11">52.45</data>
  <data key="d12">LINESTRING (-4.8413613 39.4799045, -4.8414814 39.4798489, -4.8419449 39.4797838)</data>
</edge>
<edge id="0" source="982621562" target="946409159">
  <data key="d7">483537143</data>
  <data key="d14">CM-4106</data>
  <data key="d9">secondary</data>
  <data key="d10">False</data>
  <data key="d11">104.66499999999999</data>
  <data key="d12">LINESTRING (-4.8366071 39.4783468, -4.8368979 39.4789602, -4.8371678 39.4791592)</data>
</edge>
</graph></xml>
""")

keys = {}
for key in root.findall('graph/key'):
  keys[key.get('attr.name')] = key.get('id')

key_name = keys['name']
key_length = keys['length']

out = {}
for edge in root.findall('graph/edge'):
  data = dict((d.get('key'), d.text) for d in edge.findall('data'))
  value = (data.get(key_name, 'noName'), data[key_length])
  out[(edge.get('source'), edge.get('target'))] = value

print(out)

Обратите внимание, что теперь вы получаете None для второго ребра.прежде чем он "пропал", потому что вы говорили, что это нужно отфильтровать.вместо этого мой код создает словарь на основе xml, а затем всегда заполняет значения в out кортежами, содержащими два элемента.

...