TypeError: iteration over non-sequence

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
brauns
User
Beiträge: 11
Registriert: Mittwoch 24. Oktober 2007, 14:26

Donnerstag 25. Oktober 2007, 19:32

Hallo zusammen,
jetzt habe ich nocheinmal ein kleines Python Problem, das ich nicht in den Griff bekomme.
Vielleicht habt Ihr mir auch einen Tipp ?

Ich habe jetzt ein 2. Script, welches dieses Script verwendet: http://www.python-forum.de/topic-12337.html

Der Code ist folgender:

Code: Alles auswählen

import libosm

osmfilename = 'Freiburg_17102007.osm'

print "Opening and parsing OSM file...",
osmfile = libosm.OSMFile( osmfilename )
print "done"
print "Splitting ways...",
osmfile = osmfile.split_ways()
print "done"

print "Outputting to SQL file..."

output = []    # to become list of [edge_id, from_id, to_id, cost, reverse_cost]

i=0
for id, (nodes, tags) in osmfile.ways.iteritems():

    cost = osmfile.way_length(id)
    
    if 'oneway' not in tags or (tags['oneway'] != 'true' and tags['oneway'] != 'yes'):
        reverse_cost = cost
    else:
        reverse_cost = 20000000
    
    output.append( ( i, nodes[0], nodes[-1], cost, reverse_cost ) )
    
    i += 1
    
ret = []
    
# There's a bug in pgrouting where the server crashes if two node_ids are too far apart.
# So we rename the nodes to values near zero as they go into the SQL file

i=0
osm_to_pgroute = {}

    
for way_id, from_id, to_id, length, backlength in output:
    
    #=======COPING WITH PGROUTING BUG=============
    if from_id in osm_to_pgroute:
        from_id = osm_to_pgroute[from_id]
    else:
        osm_to_pgroute[from_id] = from_id = i
        i += 1
        
    if to_id in osm_to_pgroute:
        to_id = osm_to_pgroute[to_id]
    else:
        osm_to_pgroute[to_id] = to_id = i
        i += 1
    #=======DONE COPING============================
    
    ret.append( "INSERT INTO edges VALUES (%d, %d, %d, %f, %f);"%(way_id, from_id, to_id, length, backlength) )
    
fp = open( 'routing_table.sql', 'w' )
fp.write( "\n".join(ret) )
fp.close()
Der Fehler liegt wohl an dieser Stelle:

Code: Alles auswählen

for id, (nodes, tags) in osmfile.ways.iteritems():
Hier meldet Python:
Traceback (most recent call last):
File "osm_to_pgrouting.py", line 17, in <module>
for id, (nodes, tags) in osmfile.ways.iteritems():
TypeError: iteration over non-sequence
Also habe ich wohl keine Sequenz,...
Wie kann ich die Schleife umschreiben oder fixen ?

Hat hier jemand eine Idee ?
BlackJack

Donnerstag 25. Oktober 2007, 20:41

`osmfile.ways.iteritems()` solltest Du eigentlich iterieren können. Also musst Du mal herausfinden warum das nicht geht. Ist `osmfiles.ways` das was Du denkst und sehen die Einträge auch entsprechend aus? ``print``, `type()` und `repr()` sind Deine Freunde.

Wenn das dann so läuft wie Du möchtest, solltest Du das manuelle verwalten von `i` durch `enumerate()` ersetzen.

Die ``if``-Bedingung in der Schleife lässt sich kürzer so ausdrücken:

Code: Alles auswählen

if tags.get('oneway') not in ('true', 'yes'):
brauns
User
Beiträge: 11
Registriert: Mittwoch 24. Oktober 2007, 14:26

Donnerstag 25. Oktober 2007, 21:02

Danke erstmal,
also mit den print Befehlen komme ich nicht weiter.

Augegeben wird mir sowas
4867031001L: <libosm.OSMWay instance at 0x8e55a2c>, 4555735002L: <libosm.OSMWay instance at 0x8d45e0c>,
Ist das in Ordnung ?

Wie kann ich das manuelle verwalten von i durch enumerate ersetzen ?

Leider bin ich in Python absolut nicht fit. :-(
BlackJack

Donnerstag 25. Oktober 2007, 21:14

Ob das in Ordnung ist musst Du wissen, es passt aber nicht zur Schleife. Bei dem Dictionary wird einer Zahl *ein* `OSMWay`-Objekt zugeordnet, dass heisst das ``id, (nodes, tags)`` passt nicht, weil man nicht über das `OSMWay`-Objekt iterieren kann um es auf `nodes` und `tags` zu verteilen.

Code: Alles auswählen

In [89]: x = (1, 2)

In [90]: a, (b , c) = x
---------------------------------------------------------------------------
<type 'exceptions.TypeError'>             Traceback (most recent call last)

/home/bj/<ipython console> in <module>()

<type 'exceptions.TypeError'>: 'int' object is not iterable
Zum `enumerate()`:

Code: Alles auswählen

In [91]: for i, c in enumerate('hallo'):
   ....:     print i, c
   ....:
0 h
1 a
2 l
3 l
4 o
brauns
User
Beiträge: 11
Registriert: Mittwoch 24. Oktober 2007, 14:26

Donnerstag 25. Oktober 2007, 21:52

Okay, jetzt hab ich es verstanden. Musste erstmal schnell nach googeln was ein dictonary ist.

D.h. das entweder diconary osmfile.ways falsch zusammengestellt ist oder ich muss an die inhalte id, node und tags anderst heran kommen.


Wie kann ich mir denn so ein node und ein tag aus dem array ausgeben lassen ?

geht das irgendwie so ?
print osmfile.ways[node]

Ich
BlackJack

Donnerstag 25. Oktober 2007, 22:12

Wenn Du erst googlen musst was ein Dictionary ist, dann solltest Du nochmal zu den Python-Grundlagen gehen. Zum Beispiel das Tutorial in der Doku durcharbeiten.
brauns
User
Beiträge: 11
Registriert: Mittwoch 24. Oktober 2007, 14:26

Donnerstag 25. Oktober 2007, 22:28

Ja klar das mache ich.

Jedoch verstehe ich das mit dem osmfile.way object noch nicht so ganz.

Kann man über so ein Objekt überhaupt iterieren oder muss ich das zuerst auseinander nehmen ?
BlackJack

Donnerstag 25. Oktober 2007, 22:50

Das ist ein Dictionary. Man kann direkt darüber iterieren, das ist äquivalent zum iterieren über `dictionary_object.iterkeys()`. Oder man ruft eine der Methoden auf, die etwas iterierbares zurückliefern. Die mit `iter*` lassen das ja schon vermuten. ;-)

Kann man aber auch alles nachlesen und/oder ausprobieren.

Code: Alles auswählen

In [100]: a = { 23: None, 'spam': 42 }

In [101]: for x in a: print x
   .....:
spam
23

In [102]: for x in a.iterkeys(): print x
   .....:
spam
23

In [103]: for x in a.itervalues(): print x
   .....:
42
None

In [104]: for x in a.iteritems(): print x
   .....:
('spam', 42)
(23, None)
Antworten