473,320 Members | 2,164 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Proposed new collection methods

Another thread pointed out a couple of methods that would be nice to
have on Python collections: find and inject. These are taken from
<URL: http://martinfowler.com/bliki/Collec...ureMethod.html >.

find can be defined as:

def find(self, test = None):
for item in self:
if test:
if test(item):
return item
elif item:
return item
return ValueError, '%s.index(): no matching items in list' \
% self.__class__.__name__

find with no arguments is identical to the any function <URL:
http://www.artima.com/forums/flat.js...6&thread=98196 > that
Guido has already accepted <URL:
http://mail.python.org/pipermail/pyt...ch/052010.html >,
except it's a method.

find raises a ValueError so that you can search for any value. This
also keeps it's behavior similar to index.

An alternative to adding a new method to collections would be adding a
new keyword argument - test - to the list index method. This would
remove the overlap of functionality with any. However, it would also
mean you couldn't use it on anything but lists (and presumably
strings). I'm not sure how serious a restriction that is.

inject is basically an OO version of reduce. You can define it in
terms of reduce:

def inject(self, op, init = None):
return reduce(op, self, init)

The arguments against reduce probably apply to it as well. But it
makes the pain from removing reduce vanish.

These have probably been proposed before, but under other names. If
so, I'd appreciate pointers to the discussion.

<mike
--
Mike Meyer <mw*@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
Aug 6 '05 #1
9 1347
Mike Meyer wrote:
Another thread pointed out a couple of methods that would be nice to
have on Python collections: find and inject. These are taken from
<URL: http://martinfowler.com/bliki/Collec...ureMethod.html >.

find can be defined as:

def find(self, test = None):
for item in self:
if test:
if test(item):
return item
elif item:
return item
return ValueError, '%s.index(): no matching items in list' \
% self.__class__.__name__
Dear Zeus no. Find can be defined as:
def find(self, test=lambda x:1):
try:
item = (s for s in iter(self) if test(s)).next()
except StopIteration:
raise ValueError('No matching items in list')

Let's use generators, people. And given the simplicity of writing this,
I'm not sure we need it in the standard library -- especially since the
default test is arbitrary. This recipe can also be useful for
dictionaries, where the syntax would be slightly different, and
lists-of-immutables, in which case returning the index in the list might
be better. Too much customization.
inject is basically an OO version of reduce. You can define it in
terms of reduce:


Except that if it's exactly reduce, we don't need to call it inject.
The problem with reduce in python isn't that it's functional rather than
OO, it's that it's limited to a function call or lambda -- one
expression rather than an anonymous block.
Aug 7 '05 #2
Christopher Subich wrote:
Dear Zeus no. Find can be defined as:
def find(self, test=lambda x:1):
try:
item = (s for s in iter(self) if test(s)).next()
except StopIteration:
raise ValueError('No matching items in list')


I would prefer that a find() operation return as soon as it locates an
item that passes the test. This generator version tests every item.

--
Robert Kern
rk***@ucsd.edu

"In the fields of hell where the grass grows high
Are the graves of dreams allowed to die."
-- Richard Harter

Aug 7 '05 #3
Robert Kern wrote:
Christopher Subich wrote:

Dear Zeus no. Find can be defined as:
def find(self, test=lambda x:1):
try:
item = (s for s in iter(self) if test(s)).next()
except StopIteration:
raise ValueError('No matching items in list')


I would prefer that a find() operation return as soon as it locates an
item that passes the test. This generator version tests every item.


Pardon me, I am retarded.

--
Robert Kern
rk***@ucsd.edu

"In the fields of hell where the grass grows high
Are the graves of dreams allowed to die."
-- Richard Harter

Aug 7 '05 #4
Robert Kern wrote:
Robert Kern wrote:
Christopher Subich wrote:

Dear Zeus no. Find can be defined as:
def find(self, test=lambda x:1):
try:
item = (s for s in iter(self) if test(s)).next()
except StopIteration:
raise ValueError('No matching items in list')

I would prefer that a find() operation return as soon as it locates an
item that passes the test. This generator version tests every item.

Pardon me, I am retarded.


Why are you retarded? Isn't the above code O(n)?

Forgive me for not understanding, I'm still awfully new to Python
(having come from Perl & C++), and I didn't see an explanation in the FAQ.
Aug 7 '05 #5
Jeff Schwab wrote:
Robert Kern wrote:
Robert Kern wrote:
Christopher Subich wrote:

Dear Zeus no. Find can be defined as:
def find(self, test=lambda x:1):
try:
item = (s for s in iter(self) if test(s)).next()
except StopIteration:
raise ValueError('No matching items in list')

I would prefer that a find() operation return as soon as it locates an
item that passes the test. This generator version tests every item.


Pardon me, I am retarded.


Why are you retarded? Isn't the above code O(n)?

Forgive me for not understanding, I'm still awfully new to Python
(having come from Perl & C++), and I didn't see an explanation in the FAQ.


(s for s in iter(self) is test(s)) is a generator expression. It is
roughly equivalent to

def g(self, test=lambda x: True):
for s in iter(self):
if test(s):
yield s

Now, if I were to do

item = g(self, test).next()

the generator would execute the code until it reached the yield
statement which happens when it finds the first item that passes the
test. That item will get returned, and execution does not return to the
generator again.

That implementation does indeed return as soon as it locates the first
item, so yes, I was being retarded.

--
Robert Kern
rk***@ucsd.edu

"In the fields of hell where the grass grows high
Are the graves of dreams allowed to die."
-- Richard Harter

Aug 7 '05 #6
Robert Kern wrote:
(s for s in iter(self) is test(s)) is a generator expression. It is
roughly equivalent to

def g(self, test=lambda x: True):
for s in iter(self):
if test(s):
yield s

Now, if I were to do

item = g(self, test).next()

the generator would execute the code until it reached the yield
statement which happens when it finds the first item that passes the
test. That item will get returned, and execution does not return to the
generator again.

That implementation does indeed return as soon as it locates the first
item, so yes, I was being retarded.


Wow, that's cool! Very reminiscent of C++ input iterators, but a lot
cleaner and shorter. Thanks.
Aug 7 '05 #7
Robert Kern wrote:
Jeff Schwab wrote:
Why are you retarded? Isn't the above code O(n)?

Forgive me for not understanding, I'm still awfully new to Python
(having come from Perl & C++), and I didn't see an explanation in the
FAQ.
(s for s in iter(self) is test(s)) is a generator expression. It is
roughly equivalent to [snip] That implementation does indeed return as soon as it locates the first
item, so yes, I was being retarded.


Thank you for the best programming-language related laugh I've had
today. :) I know just the kind of synapse-misfires that lead to
completely obvious, yet also completely wrong conclusions like that --
I've done well more than my own share.

For the grandparent poster: generators and its baby brother generator
expressions are the kind of really neat feature that you're never told
about in CS101. Generators themselves are relatively well-covered in
the Python documentation, which should serve as a decent introduction to
the topic.
Aug 7 '05 #8
Jeff Schwab wrote:
Robert Kern wrote:
Now, if I were to do

item = g(self, test).next()

the generator would execute the code until it reached the yield
statement which happens when it finds the first item that passes the
test. That item will get returned, and execution does not return to
the generator again.
[snip] Wow, that's cool! Very reminiscent of C++ input iterators, but a lot
cleaner and shorter. Thanks.


Read up on the __iter__ and __next__ methods that can be implemented by
objects; Python objects have a very nice way of becoming (and returning)
iterators. Generator functions and expressions are magic ways of doing
some Really Common Things as iterators.
Aug 7 '05 #9

"Mike Meyer" <mw*@mired.org> wrote in message
news:86************@bhuda.mired.org...
Another thread pointed out a couple of methods that would be nice to
have on Python collections: find and inject.
Since Python does not have a collections superclass, I am puzzled as to
what you are really proposing.
find with no arguments is identical to the any function,
except it's [find is] a method.
Again, a method of what?

The virtue of functions of iterables is that once written, the
functionality immediately becomes available to *EVERY* iterable -- for
free. Moreover, anybody can write one of the infinite number of such
functions and use it *without* begging Guido (or Mats) to please add it to
a perhaps already overly long list of methods of the collection superclass.
An alternative to adding a new method to collections would be adding a
new keyword argument - test - to the list index method. This would
remove the overlap of functionality with any. However, it would also
mean you couldn't use it on anything but lists (and presumably
strings). I'm not sure how serious a restriction that is.
Compared to the infinite universe of possible iterables, the restriction is
pretty severe. Index should perhaps be turned into a universal iterable
function. You could suggest that any() get an optional keyword or 2nd
param.

In Python, generic functions are functions. Methods are functions properly
restricted to one or a few classes and perhaps subclasses.
def inject(self, op, init = None):
return reduce(op, self, init)


You aren't seriously suggesting that reduce be renamed to something more
obscure, even contradictory, are you? Inject means to add something into,
while reduce usually means to pull a summary out of. Perhaps I missed
something.

Terry J. Reedy

Aug 8 '05 #10

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

Similar topics

99
by: David MacQuigg | last post by:
I'm not getting any feedback on the most important benefit in my proposed "Ideas for Python 3" thread - the unification of methods and functions. Perhaps it was buried among too many other less...
0
by: Anthony Baxter | last post by:
To go along with the 2.4a3 release, here's an updated version of the decorator PEP. It describes the state of decorators as they are in 2.4a3. PEP: 318 Title: Decorators for Functions and...
125
by: Raymond Hettinger | last post by:
I would like to get everyone's thoughts on two new dictionary methods: def count(self, value, qty=1): try: self += qty except KeyError: self = qty def appendlist(self, key, *values): try:
7
by: Jon Davis | last post by:
I'm managing "collections" / "lists" (??) of objects that are internally bound by an XML document, but I do NOT intend to offer an IEnumerator interface. For instance, with a root XML document,...
3
by: Dave | last post by:
Please - anyone that can help. I am getting confusing results while trying to expose a collection from a web service. I have a webservice in which a web method accepts a collection as a...
4
by: Martin Widmer | last post by:
Hi folks. I am using this collection class: Public Class ContentBlocksCollection Inherits DictionaryBase 'Object variables for attributes 'Attributes Default Public Property Item(ByVal...
6
by: Arthur Dent | last post by:
How do you sort a generic collection derived from System.Collections.ObjectModel.Collection? Thanks in advance, - Arthur Dent
3
by: James J. Besemer | last post by:
I would like to champion a proposed enhancement to Python. I describe the basic idea below, in order to gage community interest. Right now, it's only an idea, and I'm sure there's room for...
7
by: Dale | last post by:
I have a design question. I am creating a custom collection of products. The unique key for the products is productId which is an integer. By default, IndexOf(object obj), when obj is an int,...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....

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.