473,508 Members | 2,342 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

appending to a list via properties

Here's a curious hack I want to put up for discussion. I'm thinking of
writing a PEP for it.

Observation
-----------------
I found myself using this construct for assembling multiple lists:

foo = []
qux = []

while some_condition:
a, b = calculate_something()
foo.append(a)
qux.append(b)

Not elegant! It requires temporary variables a and b, which are only
used to populate the lists.
Suggestion
----------------

class better_list (list):
tail = property(None, list.append)

foo = better_list()
qux = better_list()

while some_condition:
foo.tail, qux.tail = calculate_something()

Granted, the name tail might not be the best, but you get the idea.
Alternatives
------------------

1. Use "append" instead, preserving original list.append behavior.

class better_list (list):
append = property(lambda l: lambda x: list.append(l,x),
list.append)

2. Use an external wrapper, similar to operator.*getter

class propertize (object):
def __init__(self, target):
self.__target__ = target
def __setattr__(self, attribute, value):
if attribute.startswith('_'): return
object.__setattr__(self, attribute, value)
else: getattr(self.__target__, attribute)(value)

propertize(foo).append, propertize(qux).append =
calculate_something()
Well?

Feb 10 '06 #1
7 5158
Lonnie Princehouse wrote:
Here's a curious hack I want to put up for discussion. I'm thinking of
writing a PEP for it.

Observation
-----------------
I found myself using this construct for assembling multiple lists:

foo = []
qux = []

while some_condition:
a, b = calculate_something()
foo.append(a)
qux.append(b)

Not elegant! It requires temporary variables a and b, which are only
used to populate the lists.
Suggestion
----------------

class better_list (list):
tail = property(None, list.append)

foo = better_list()
qux = better_list()

while some_condition:
foo.tail, qux.tail = calculate_something()

Granted, the name tail might not be the best, but you get the idea.
Alternatives
------------------

1. Use "append" instead, preserving original list.append behavior.

class better_list (list):
append = property(lambda l: lambda x: list.append(l,x),
list.append)

2. Use an external wrapper, similar to operator.*getter

class propertize (object):
def __init__(self, target):
self.__target__ = target
def __setattr__(self, attribute, value):
if attribute.startswith('_'): return
object.__setattr__(self, attribute, value)
else: getattr(self.__target__, attribute)(value)

propertize(foo).append, propertize(qux).append =
calculate_something()
Well?

Not entirely sure I understand, but here goes. I normally
use list comprehensions. I'm assuming that calculate_something()
is acting on a list of items. If not then maybe some underlying
data refactoring is in order. If so you write:

results=[calculate_something(x) for x in list_of_items]
foo=result[x[0] for x in results]
qux=result[x[1] for x in results]

Without knowing more about what calculate_something() does
and what condition terminates the loop it is hard to say if
this will work for you.

-Larry Bates
Feb 10 '06 #2
Lonnie Princehouse wrote:
Here's a curious hack I want to put up for discussion. I'm thinking of
writing a PEP for it.
A minor library change wouldn' t need a PEP.
Observation
-----------------
I found myself using this construct for assembling multiple lists:

foo = []
qux = []

while some_condition:
a, b = calculate_something()
foo.append(a)
qux.append(b)

Not elegant!
I don't agree; however:
class better_list (list):
tail = property(None, list.append)
This is an impressive, spiffy little class.
Well?


I suspect it's too sneaky and not commonly useful enough to get serious
consideration for the standard library. But definitely submit it to
Python Cookbook:
http://aspn.activestate.com/ASPN/Python/Cookbook/

Carl Banks
P.S. to get rid of temporary variables while using regular lists:

growing_lists = foo,qux
while some_condition:
for (s,x) in zip(growing_list,calculate_something()):
list.append(s,x)

No I don't really recommend it.

Feb 11 '06 #3
Carl Banks <in**********@aerojockey.com> wrote:
...
class better_list (list):
tail = property(None, list.append)
This is an impressive, spiffy little class.


Yes, nice use of property.
growing_lists = foo,qux
while some_condition:
for (s,x) in zip(growing_list,calculate_something()):
list.append(s,x)

No I don't really recommend it.


Why not? Seems OK. Maybe simplified to:

while some_condition:
for alist, anitem in zip((foo, qux), calculate_something()):
alist.append(anitem)

If you want to hoist for performance, you can hoist more:

appenders = foo.append, qux.append
while some_condition:
for appender, anitem in zip(appenders, calculate_something()):
appender(anitem)
Alex
Feb 11 '06 #4

Alex Martelli wrote:
Carl Banks <in**********@aerojockey.com> wrote:
...
class better_list (list):
tail = property(None, list.append)


This is an impressive, spiffy little class.


Yes, nice use of property.
growing_lists = foo,qux
while some_condition:
for (s,x) in zip(growing_list,calculate_something()):
list.append(s,x)

No I don't really recommend it.


Why not? Seems OK. Maybe simplified to:


Well, for this simple case I guess. If you have a lot of lists, or
you're trying to write a general multiple list appender, it would be
fine.

Carl Banks

Feb 11 '06 #5
Alex Martelli wrote:
Carl Banks <in**********@aerojockey.com> wrote:
...
class better_list (list):
tail = property(None, list.append)

This is an impressive, spiffy little class.


Yes, nice use of property.

Alex


I don't know, I usually see people considering that properties are
"cool" as long as they don't have side effects, as long as they're
virtual members.

The tail property doesn't behave like member data at all, the semantics
are strange, counter-intuitive (tail would usually be the end of the
list, either [-1] or [1:], in this case it's some magic position at the
end of the list). And it has one hell of a side effect.
Feb 12 '06 #6
Xavier Morel <xa**********@masklinn.net> wrote:
Alex Martelli wrote:
Carl Banks <in**********@aerojockey.com> wrote:
...
class better_list (list):
tail = property(None, list.append)
This is an impressive, spiffy little class.
Yes, nice use of property.

Alex


I don't know, I usually see people considering that properties are
"cool" as long as they don't have side effects, as long as they're
virtual members.


If a property didn't have any side effects, there would be no reason to
define it as a property. I do fully expect x.y=z to have "side effects"
on z when y is an assignable property.
The tail property doesn't behave like member data at all, the semantics
are strange, counter-intuitive (tail would usually be the end of the
list, either [-1] or [1:], in this case it's some magic position at the
end of the list). And it has one hell of a side effect.


The name 'tail' may not be ideal (for people coming from languages where
'head' is the first element and 'tail' is all the others, in
particular). But the side effect doesn't look hellish at all to me.
Alex
Feb 12 '06 #7
[Alex Martelli]
If you want to hoist for performance, you can hoist more:

appenders = foo.append, qux.append
while some_condition:
for appender, anitem in zip(appenders, calculate_something()):
appender(anitem)
You are of course claiming a performance improvement over Carl's variant,
but looking back into the initial post

[Lonnie Princehouse]
foo = []
qux = []

while some_condition:
a, b = calculate_something()
foo.append(a)
qux.append(b)


the original code looks like yours with the inner loop unrolled - a classic
measure for performance improvement.

$ python -m timeit -s'ext = [].extend, [].extend' -s'def calc(): return (),
()' 'for ix, i in zip(ext, calc()): ix(i)'
100000 loops, best of 3: 2.79 usec per loop

$ python -m timeit -s'ax = [].extend; bx = [].extend' -s'def calc(): return
(), ()' 'a, b = calc(); ax(a); bx(b)'
1000000 loops, best of 3: 0.975 usec per loop

(I used extend instead of append() to avoid the effects of memory hogging)

I find the faster code more readable than yours - and Lonnie's cool hack -
so I'd leave it at that.

Peter

Feb 12 '06 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
3173
by: bucket79 | last post by:
Hi is there anyway appending to dictionary? list has this feature >>>a = >>>a.append(1) >>>print a but dictionary can't
5
1878
by: rbt | last post by:
I know how to setup an empty list and loop thru something... appending to the list on each loop... how does this work with dicts? I'm looping thru a list of files and I want to put the file's...
7
1300
by: DataSmash | last post by:
I'm confused. Why is it that when I say "while len(list) < 5:", I get 5 items in my list. If I say "while len(list) < 6:", I get 6 items in the list and so on. I would think if I said "less than...
1
2281
by: Ron Adam | last post by:
In my program I have a lot of statements that append elements, but sometimes I don't want to append the element so it requres an if statement to check it, and that requires assigning the returned...
7
1792
by: joecap5 | last post by:
I have a main window from which I want to open a separate side menu window. I then want to create a list of items on that side menu by clicking on the item names in the main window. So far I am...
10
15000
by: Debajit Adhikary | last post by:
I have two lists: a = b = What I'd like to do is append all of the elements of b at the end of a, so that a looks like: a =
1
1183
by: irixdude | last post by:
I am trying to create a script to enter the values of an array into a dynamically generated table 3 columns wide. I have a counter for the row # that I am using to name/id the row TR node so I an...
4
1479
by: John [H2O] | last post by:
I have a glob.glob search: searchstring = os.path.join('path'+'EN*') files = glob.glob(searchstring) for f in files: print f ___ This returns some files:
13
3208
by: yueying53 | last post by:
I am new to creating a list of classes. Hence I checked out this website: http://www.daniweb.com/code/snippet390.html. However, I modified the code to check if a class with a particular has been...
0
7229
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7333
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
7061
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
7502
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
1
5057
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
4716
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3208
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
1
769
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
428
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.