Enumerating ordered expat attributes with tuplets?

A

andy_westken

Hi

I'm new to Python and trying to pick up good, idiomatic usage right
from the offset.

As I was familiar with Expat from C++ (directly and via expatpp) I'm
trying to write a little script - using xml.parsers.expat - to search
and replace XML attribute values.

As I want the attributes to stay in order when the file is written out
(so I can check my results with a diff tool) I've set the parser's
ordered_attributes attribute. But this has stopped the for loop
working with the tuplets.

The relevant bit of code in my little test, using the default
Dictionary for the attributes, is:

def start_element(name, attrs):
print "%s : " % name,
for (a,b) in attrs.items():
print " %s=\"%s\"" % (a,b),

But when I set ordered_attributes, first it doesn't like the items()

AttributeError: 'list' object has no attribute 'items'

And then it doesn't like the tuple

ValueError: too many values to unpack

Do I have keep track of where I am (name, value, name, value, ...)

Or is there a way I can solve the problem with a tuple?

Thanks, Andy
 
M

Manuel Ebert

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi Andy,

by the looks of it I'd say that the problem is that the second
parameter you passed to start_element is not a dictionary at all (the
clue is in the "AttributeError: 'LIST' object" ...).
>>> d = ['tree', 'house']
>>> start_element("Thing", d)
Thing :
AttributeError: 'list' object has no attribute 'items'Thing : flower="eat" tree="hug"

Manuel

Hi

I'm new to Python and trying to pick up good, idiomatic usage right
from the offset.

As I was familiar with Expat from C++ (directly and via expatpp) I'm
trying to write a little script - using xml.parsers.expat - to search
and replace XML attribute values.

As I want the attributes to stay in order when the file is written out
(so I can check my results with a diff tool) I've set the parser's
ordered_attributes attribute. But this has stopped the for loop
working with the tuplets.

The relevant bit of code in my little test, using the default
Dictionary for the attributes, is:

def start_element(name, attrs):
print "%s : " % name,
for (a,b) in attrs.items():
print " %s=\"%s\"" % (a,b),

But when I set ordered_attributes, first it doesn't like the items()

AttributeError: 'list' object has no attribute 'items'

And then it doesn't like the tuple

ValueError: too many values to unpack

Do I have keep track of where I am (name, value, name, value, ...)

Or is there a way I can solve the problem with a tuple?

Thanks, Andy

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (Darwin)

iD8DBQFIyTOLcZ70OCIgLecRAsBrAJ9YSa7f+YTyM1yRmEKw8KBtb2klIgCgjNzw
F295Tik+45eNHnJ3B4kKnWU=
=xR4m
-----END PGP SIGNATURE-----
 
A

andy_westken

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi Andy,

by the looks of it I'd say that the problem is that the second  
parameter you passed to start_element is not a dictionary at all (the  
clue is in the "AttributeError: 'LIST' object" ...).

 >>> d = ['tree', 'house']
 >>> start_element("Thing", d)
Thing :
AttributeError: 'list' object has no attribute 'items'
 >>> d = {'tree': 'hug', 'flower' : 'eat'}
 >>> start_element("Thing", d)
Thing :   flower="eat"  tree="hug"

Manuel

I'm new to Python and trying to pick up good, idiomatic usage right
from the offset.
As I was familiar with Expat from C++ (directly and via expatpp) I'm
trying to write a little script - using xml.parsers.expat - to search
and replace XML attribute values.
As I want the attributes to stay in order when the file is written out
(so I can check my results with a diff tool) I've set the parser's
ordered_attributes attribute. But this has stopped the for loop
working with the tuplets.
The relevant bit of code in my little test, using the default
Dictionary for the attributes, is:
def start_element(name, attrs):
    print "%s : " % name,
    for (a,b) in attrs.items():
        print " %s=\"%s\"" % (a,b),
But when I set ordered_attributes, first it doesn't like the items()
    AttributeError: 'list' object has no attribute 'items'
And then it doesn't like the tuple
    ValueError: too many values to unpack
Do I have keep track of where I am (name, value, name, value, ...)
Or is there a way I can solve the problem with a tuple?
Thanks, Andy

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (Darwin)

iD8DBQFIyTOLcZ70OCIgLecRAsBrAJ9YSa7f+YTyM1yRmEKw8KBtb2klIgCgjNzw
F295Tik+45eNHnJ3B4kKnWU=
=xR4m
-----END PGP SIGNATURE------ Hide quoted text -

- Show quoted text -

Sorry!

I forgot to mention that when you set the parser's ordered_attributes
attribute, it sends the "attrs" to start_element as a list, not a
dictionary, in the order name, value, name, value, ...

Andy
 
M

Manuel Ebert

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Ah, well. Don't know whether it meets your aesthetic standards, but:
>>> my_list = ['tree', 'hug', 'flower', 'hug', 'bear', 'run']
>>> my_list[0:len(a):2] ['tree', 'flower', 'bear']
>>> my_list[1:len(a):2]
['hug', 'hug', 'run']

and hence
>>> zip(my_list[0:len(a):2], my_list[1:len(a):2])
[('tree', 'hug'), ('flower', 'hug'), ('bear', 'run')]

and furthermore
>>> for a, b in zip(my_list[0:len(a):2], my_list[1:len(a):2]):
.... print a, b
....
tree hug
flower hug
bear run

or the slightly less obfuscated:
.... print my_list[index], my_list[index + 1]
....
tree hug
flower hug
bear run

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi Andy,

by the looks of it I'd say that the problem is that the second
parameter you passed to start_element is not a dictionary at all (the
clue is in the "AttributeError: 'LIST' object" ...).
d = ['tree', 'house']
start_element("Thing", d)
Thing :
AttributeError: 'list' object has no attribute 'items'
d = {'tree': 'hug', 'flower' : 'eat'}
start_element("Thing", d)
Thing : flower="eat" tree="hug"

Manuel

I'm new to Python and trying to pick up good, idiomatic usage right
from the offset.
As I was familiar with Expat from C++ (directly and via expatpp) I'm
trying to write a little script - using xml.parsers.expat - to
search
and replace XML attribute values.
As I want the attributes to stay in order when the file is
written out
(so I can check my results with a diff tool) I've set the parser's
ordered_attributes attribute. But this has stopped the for loop
working with the tuplets.
The relevant bit of code in my little test, using the default
Dictionary for the attributes, is:
def start_element(name, attrs):
print "%s : " % name,
for (a,b) in attrs.items():
print " %s=\"%s\"" % (a,b),
But when I set ordered_attributes, first it doesn't like the items()
AttributeError: 'list' object has no attribute 'items'
And then it doesn't like the tuple
ValueError: too many values to unpack
Do I have keep track of where I am (name, value, name, value, ...)
Or is there a way I can solve the problem with a tuple?
Thanks, Andy

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (Darwin)

iD8DBQFIyTOLcZ70OCIgLecRAsBrAJ9YSa7f+YTyM1yRmEKw8KBtb2klIgCgjNzw
F295Tik+45eNHnJ3B4kKnWU=
=xR4m
-----END PGP SIGNATURE------ Hide quoted text -

- Show quoted text -

Sorry!

I forgot to mention that when you set the parser's ordered_attributes
attribute, it sends the "attrs" to start_element as a list, not a
dictionary, in the order name, value, name, value, ...

Andy

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (Darwin)

iD8DBQFIyT25cZ70OCIgLecRAmWqAJ4zEy8gatIh4CqKpJxZwACs9BBxgwCfaPoQ
QfmRVzHqwJFu3WnjCM0TJYo=
=9z6U
-----END PGP SIGNATURE-----
 
A

andy_westken

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Ah, well. Don't know whether it meets your aesthetic standards, but:
 >>> my_list = ['tree', 'hug', 'flower', 'hug', 'bear', 'run']
 >>> my_list[0:len(a):2]
['tree', 'flower', 'bear']
 >>> my_list[1:len(a):2]
['hug', 'hug', 'run']

and hence

 >>> zip(my_list[0:len(a):2], my_list[1:len(a):2])
[('tree', 'hug'), ('flower', 'hug'), ('bear', 'run')]

and furthermore

 >>> for a, b in zip(my_list[0:len(a):2], my_list[1:len(a):2]):
...     print a, b
...
tree hug
flower hug
bear run

or the slightly less obfuscated:

 >>> for index in range(0, len(my_list), 2):
...     print my_list[index], my_list[index + 1]
...    
tree hug
flower hug
bear run

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hi Andy,
by the looks of it I'd say that the problem is that the second
parameter you passed to start_element is not a dictionary at all (the
clue is in the "AttributeError: 'LIST' object" ...).
 >>> d = ['tree', 'house']
 >>> start_element("Thing", d)
Thing :
AttributeError: 'list' object has no attribute 'items'
 >>> d = {'tree': 'hug', 'flower' : 'eat'}
 >>> start_element("Thing", d)
Thing :   flower="eat"  tree="hug"
Manuel
On Sep 11, 2008, at 4:21 PM, (e-mail address removed) wrote:
Hi
I'm new to Python and trying to pick up good, idiomatic usage right
from the offset.
As I was familiar with Expat from C++ (directly and via expatpp) I'm
trying to write a little script - using xml.parsers.expat - to  
search
and replace XML attribute values.
As I want the attributes to stay in order when the file is  
written out
(so I can check my results with a diff tool) I've set the parser's
ordered_attributes attribute. But this has stopped the for loop
working with the tuplets.
The relevant bit of code in my little test, using the default
Dictionary for the attributes, is:
def start_element(name, attrs):
    print "%s : " % name,
    for (a,b) in attrs.items():
        print " %s=\"%s\"" % (a,b),
But when I set ordered_attributes, first it doesn't like the items()
    AttributeError: 'list' object has no attribute 'items'
And then it doesn't like the tuple
    ValueError: too many values to unpack
Do I have keep track of where I am (name, value, name, value, ...)
Or is there a way I can solve the problem with a tuple?
Thanks, Andy
--
http://mail.python.org/mailman/listinfo/python-list
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (Darwin)
iD8DBQFIyTOLcZ70OCIgLecRAsBrAJ9YSa7f+YTyM1yRmEKw8KBtb2klIgCgjNzw
F295Tik+45eNHnJ3B4kKnWU=
=xR4m
-----END PGP SIGNATURE------ Hide quoted text -
- Show quoted text -

I forgot to mention that when you set the parser's ordered_attributes
attribute, it sends the "attrs" to start_element as a list, not a
dictionary, in the order name, value, name, value, ...

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (Darwin)

iD8DBQFIyT25cZ70OCIgLecRAmWqAJ4zEy8gatIh4CqKpJxZwACs9BBxgwCfaPoQ
QfmRVzHqwJFu3WnjCM0TJYo=
=9z6U
-----END PGP SIGNATURE------ Hide quoted text -

- Show quoted text -

Thanks!

Regarding aesthetics - I don't need it to look pretty: I want it to be
understandable to people who know Python (?), and then as efficient as
possible.

Of the two examples about (the 'zip' solution and the 'range'
solution), is there much difference in performance?

Andy
 
M

MRAB

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Ah, well. Don't know whether it meets your aesthetic standards, but:
 >>> my_list = ['tree', 'hug', 'flower', 'hug', 'bear', 'run']
 >>> my_list[0:len(a):2]
['tree', 'flower', 'bear']
 >>> my_list[1:len(a):2]
['hug', 'hug', 'run']

and hence

 >>> zip(my_list[0:len(a):2], my_list[1:len(a):2])
[('tree', 'hug'), ('flower', 'hug'), ('bear', 'run')]

and furthermore

 >>> for a, b in zip(my_list[0:len(a):2], my_list[1:len(a):2]):
...     print a, b
...
tree hug
flower hug
bear run

or the slightly less obfuscated:

 >>> for index in range(0, len(my_list), 2):
...     print my_list[index], my_list[index + 1]
...    
tree hug
flower hug
bear run
[snip]
I don't know what the "len(a)" is, but the end position defaults to
the end:
zip(my_list[0::2], my_list[1::2])
[('tree', 'hug'), ('flower', 'hug'), ('bear', 'run')]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top