468,471 Members | 1,653 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,471 developers. It's quick & easy.

Misuse of list comprehensions?

I posted this code last night in response to another thread, and after I
posted it I got to wondering if I had misused the list comprehension. Here's
the two examples:

Example 1:
--------------------
def compress(s):
new = []

for c in s:
if c not in new:
new.append(c)
return ''.join(new)
----------------------

Example 2:
------------------------
def compress(s):
new = []
[new.append(c) for c in s if c not in new]
return ''.join(new)
--------------------------

In example 1, the intention to make an in-place change is explicit, and it's
being used as everyone expects it to be used. In example 2, however, I began
to think this might be an abuse of list comprehensions, because I'm not
assigning the result to anything (nor am I even using the result in any
way).

What does everyone think about this? Should list comprehensions be used this
way, or should they only be used to actually create a new list that will
then be assigned to a variable/returned/etc.?
Jun 27 '08 #1
31 1036
John Salerno wrote:
I posted this code last night in response to another thread, and after I
posted it I got to wondering if I had misused the list comprehension.
Here's the two examples:

Example 1:
--------------------
def compress(s):
new = []

for c in s:
if c not in new:
new.append(c)
return ''.join(new)
----------------------

Example 2:
------------------------
def compress(s):
new = []
[new.append(c) for c in s if c not in new]
return ''.join(new)
--------------------------

In example 1, the intention to make an in-place change is explicit, and
it's being used as everyone expects it to be used. In example 2, however,
I began to think this might be an abuse of list comprehensions, because
I'm not assigning the result to anything (nor am I even using the result
in any way).
What does everyone think about this? Should list comprehensions be used
this way, or should they only be used to actually create a new list that
will then be assigned to a variable/returned/etc.?
the above code is pretty much of a no-no because it has quadratic runtime
behavior.

That being said, I use that idiom myself. But I don't see anything wrong
with using a list-comp as loop-abbreviation. because that is it's actual
purpose. And also it is common in non-functional languages that l-values
aren't always assigned, if the aren't needed. It's the consequence of
having side-effects in a language - and python has them.

Diez
Jun 27 '08 #2
John Salerno:
What does everyone think about this?
The Example 2 builds a list, that is then thrown away. It's just a
waste of memory (and time).

Bye,
bearophile
Jun 27 '08 #3
be************@lycos.com wrote:
John Salerno:
>What does everyone think about this?

The Example 2 builds a list, that is then thrown away. It's just a
waste of memory (and time).
No, it doesn't. It uses append because it refers to itself in the
if-expression. So the append(c) is needed - and thus the assignment
possible but essentially useless.

Diez
Jun 27 '08 #4
John Salerno a écrit :
I posted this code last night in response to another thread, and after I
posted it I got to wondering if I had misused the list comprehension.
(snip)
def compress(s):
new = []
[new.append(c) for c in s if c not in new]
return ''.join(new)
As far as I'm concerned (and I'm a big fan of list-comps, generator
expressions etc), this is definitively an abuse. And a waste of
resources since it builds a useless list of 'None'.
Jun 27 '08 #5
"Diez B. Roggisch" <de***@nospam.web.dewrites:
be************@lycos.com wrote:
>John Salerno:
>>What does everyone think about this?

The Example 2 builds a list, that is then thrown away. It's just a
waste of memory (and time).

No, it doesn't.
This line:

[new.append(c) for c in s if c not in new]

....throws away the list built by the comprehension itself, composed of
None values (returned by append).
It uses append because it refers to itself in the if-expression. So
the append(c) is needed
The append is not in question here.
Jun 27 '08 #6
Hrvoje Niksic wrote:
"Diez B. Roggisch" <de***@nospam.web.dewrites:
>be************@lycos.com wrote:
>>John Salerno:
What does everyone think about this?

The Example 2 builds a list, that is then thrown away. It's just a
waste of memory (and time).

No, it doesn't.

This line:

[new.append(c) for c in s if c not in new]

...throws away the list built by the comprehension itself, composed of
None values (returned by append).
Ah. You are right of course.

Diez
Jun 27 '08 #7
That being said, I use that idiom myself. But I don't see anything wrong
with using a list-comp as loop-abbreviation. because that is it's actual
purpose. And also it is common in non-functional languages that l-values
aren't always assigned, if the aren't needed. It's the consequence of
having side-effects in a language - and python has them.
After being corrected about missing the construction of a None-containing
list, one needs of course to think about the waste of resources, as a
possible result-list is created in any case.

I personally still don't mind that (if we talk about a few hundred objects a
top) - but it makes a strong point against a general usage.

Diez
Jun 27 '08 #8
Thomas Bellman wrote:
"Diez B. Roggisch" <de***@nospam.web.dewrites:
>be************@lycos.com wrote:
>>The Example 2 builds a list, that is then thrown away. It's just a
waste of memory (and time).
>No, it doesn't. It uses append because it refers to itself in the
if-expression. So the append(c) is needed - and thus the assignment
possible but essentially useless.

Yes it does. A list comprehension *always* creates a list. In
this case it will be a list of None, since that is what list.append()
returns. See this:
Yep - no idea how that slipped me. I still don't mind the occasional waste
of a list-creation over a more concise looping-construct, but I totally
admit that one has to be aware of this. more than I was....

Diez
Jun 27 '08 #9
On May 20, 8:13*am, "John Salerno" <johnj...@NOSPAMgmail.comwrote:
I posted this code last night in response to another thread, and after I
posted it I got to wondering if I had misused the list comprehension. Here's
the two examples:

Example 1:
--------------------
def compress(s):
* * new = []

* * for c in s:
* * * * if c not in new:
* * * * * * new.append(c)
* * return ''.join(new)
----------------------

Example 2:
------------------------
def compress(s):
* * new = []
* * [new.append(c) for c in s if c not in new]
* * return ''.join(new)
--------------------------

In example 1, the intention to make an in-place change is explicit, and it's
being used as everyone expects it to be used. In example 2, however, I began
to think this might be an abuse of list comprehensions, because I'm not
assigning the result to anything (nor am I even using the result in any
way).

What does everyone think about this? Should list comprehensions be used this
way, or should they only be used to actually create a new list that will
then be assigned to a variable/returned/etc.?
Why not make the list comp the actual list you are trying to build?

def compress(s):
seen = set()
new = [c for c in s if c not in seen and (seen.add(c) or True)]
return ''.join(new)

or just:

def compress(s):
seen = set()
return ''.join(c for c in s if c not in seen and (seen.add(c) or
True))

Using the set also gets rid of that nasty quadratic performance
thingy.

-- Paul
Jun 27 '08 #10
Paul McGuire <pt***@austin.rr.comwrites:
On May 20, 8:13*am, "John Salerno" <johnj...@NOSPAMgmail.comwrote:
>I posted this code last night in response to another thread, and after I
posted it I got to wondering if I had misused the list comprehension. Here's
the two examples:

Example 1:
--------------------
def compress(s):
* * new = []

* * for c in s:
* * * * if c not in new:
* * * * * * new.append(c)
* * return ''.join(new)
----------------------

Example 2:
------------------------
def compress(s):
* * new = []
* * [new.append(c) for c in s if c not in new]
* * return ''.join(new)
--------------------------

In example 1, the intention to make an in-place change is explicit, and it's
being used as everyone expects it to be used. In example 2, however, I began
to think this might be an abuse of list comprehensions, because I'm not
assigning the result to anything (nor am I even using the result in any
way).

What does everyone think about this? Should list comprehensions be used this
way, or should they only be used to actually create a new list that will
then be assigned to a variable/returned/etc.?

Why not make the list comp the actual list you are trying to build?

def compress(s):
seen = set()
new = [c for c in s if c not in seen and (seen.add(c) or True)]
<split hairs>
Isn't

c not in seen and (seen.add(c) or True)

the same as

seen.add(c) or c not in seen

?
return ''.join(new)
(notice I haven't closed the tag!)

--
Arnaud
Jun 27 '08 #11
On May 20, 9:58 am, Paul McGuire <pt...@austin.rr.comwrote:
On May 20, 8:13 am, "John Salerno" <johnj...@NOSPAMgmail.comwrote:
I posted this code last night in response to another thread, and after I
posted it I got to wondering if I had misused the list comprehension. Here's
the two examples:
Example 1:
--------------------
def compress(s):
new = []
for c in s:
if c not in new:
new.append(c)
return ''.join(new)
----------------------
Example 2:
------------------------
def compress(s):
new = []
[new.append(c) for c in s if c not in new]
return ''.join(new)
--------------------------
In example 1, the intention to make an in-place change is explicit, and it's
being used as everyone expects it to be used. In example 2, however, I began
to think this might be an abuse of list comprehensions, because I'm not
assigning the result to anything (nor am I even using the result in any
way).
What does everyone think about this? Should list comprehensions be used this
way, or should they only be used to actually create a new list that will
then be assigned to a variable/returned/etc.?

Why not make the list comp the actual list you are trying to build?

def compress(s):
seen = set()
new = [c for c in s if c not in seen and (seen.add(c) or True)]
return ''.join(new)

or just:

def compress(s):
seen = set()
return ''.join(c for c in s if c not in seen and (seen.add(c) or
True))

Using the set also gets rid of that nasty quadratic performance
thingy.
You don't need all those conditionals. A set differs from a list
precisely in the fact that each element is unique. And since the
function is expecting "s" to be an iterable object, it can be
constructed even without a for loop:

def compress(s):
return list(set(s))

That does the trick.
Jun 27 '08 #12
On May 20, 10:17*am, Arnaud Delobelle <arno...@googlemail.comwrote:
Paul McGuire <pt...@austin.rr.comwrites:
On May 20, 8:13*am, "John Salerno" <johnj...@NOSPAMgmail.comwrote:
I posted this code last night in response to another thread, and after I
posted it I got to wondering if I had misused the list comprehension. Here's
the two examples:
Example 1:
--------------------
def compress(s):
* * new = []
* * for c in s:
* * * * if c not in new:
* * * * * * new.append(c)
* * return ''.join(new)
----------------------
Example 2:
------------------------
def compress(s):
* * new = []
* * [new.append(c) for c in s if c not in new]
* * return ''.join(new)
--------------------------
In example 1, the intention to make an in-place change is explicit, andit's
being used as everyone expects it to be used. In example 2, however, I began
to think this might be an abuse of list comprehensions, because I'm not
assigning the result to anything (nor am I even using the result in any
way).
What does everyone think about this? Should list comprehensions be usedthis
way, or should they only be used to actually create a new list that will
then be assigned to a variable/returned/etc.?
Why not make the list comp the actual list you are trying to build?
def compress(s):
* * seen = set()
* * new = [c for c in s if c not in seen and (seen.add(c) or True)]

<split hairs>
Isn't

* * c not in seen and (seen.add(c) or True)

the same as

* * seen.add(c) or c not in seen

?
* * return ''.join(new)

(notice I haven't closed the tag!)

--
Arnaud- Hide quoted text -

- Show quoted text -
Unfortunately, no. "seen.add(c) or c not in seen" will never return
true, since c gets added to seen before testing if c in seen.

-- Paul
Jun 27 '08 #13
On May 20, 3:58 pm, Paul McGuire <pt...@austin.rr.comwrote:
def compress(s):
seen = set()
return ''.join(c for c in s if c not in seen and (seen.add(c) or
True))
Slightly nicer is to move the set add out of the conditional...

def compress(s):
seen = set()
return ''.join(seen.add(c) or c for c in s if c not in seen)

I wouldn't write it this way though :)

--
Paul Hankin
Jun 27 '08 #14
"Diez B. Roggisch" <de***@nospam.web.dewrote in message
news:69*************@mid.uni-berlin.de...
the above code is pretty much of a no-no because it has quadratic runtime
behavior.

What's that mean, exactly? Are you referring to both examples, or just the
second one?
Jun 27 '08 #15
Paul McGuire <pt***@austin.rr.comwrites:
On May 20, 10:17*am, Arnaud Delobelle <arno...@googlemail.comwrote:
[...]
><split hairs>
Isn't

* * c not in seen and (seen.add(c) or True)

the same as

* * seen.add(c) or c not in seen

?
* * return ''.join(new)

(notice I haven't closed the tag!)

--
Arnaud- Hide quoted text -

- Show quoted text -

Unfortunately, no. "seen.add(c) or c not in seen" will never return
true, since c gets added to seen before testing if c in seen.

-- Paul
Ha you're right of course. But I haven't closed the tag yet, so:

c not in seen and (seen.add(c) or True)

is definitely the same as

c not in seen and not seen.add(c)

which is

not (c in seen or seen.add(c))

:)

</split hairs>

--
Arnaud
Jun 27 '08 #16
"Diez B. Roggisch" <de***@nospam.web.dewrote in message
news:69*************@mid.uni-berlin.de...
After being corrected about missing the construction of a None-containing
list, one needs of course to think about the waste of resources, as a
possible result-list is created in any case.
Yeah, I was already aware of the list of Nones, which is why I asked. Simply
typing the list comprehension without an assignment just *looked* wrong,
too.
Jun 27 '08 #17
"Bruno Desthuilliers" <br********************@websiteburo.invalidwrote in
message news:48***********************@news.free.fr...
>def compress(s):
new = []
[new.append(c) for c in s if c not in new]
return ''.join(new)

As far as I'm concerned (and I'm a big fan of list-comps, generator
expressions etc), this is definitively an abuse. And a waste of resources
since it builds a useless list of 'None'.
I agree with you. After being proud of myself for about 20 seconds, it
suddenly seemed like an abuse rather than a clever way to do it in one line.
:) It just looked wrong to have a list comp. without an assignment, etc.

Actually, though, I wasn't so much thinking of the waste of resources as I
was that what was happening didn't seem to be explicit or evident enough. So
despite the fact that the for loop with the nested if is the exact same
code, it just seems more appropriate.
Jun 27 '08 #18

"John Salerno" <jo******@NOSPAMgmail.comwrote in message
news:02**********************@news.astraweb.com...
| "Diez B. Roggisch" <de***@nospam.web.dewrote in message
| news:69*************@mid.uni-berlin.de...
| the above code is pretty much of a no-no because it has quadratic
runtime
| behavior.
|
|
| What's that mean, exactly? Are you referring to both examples, or just
the
| second one?

Both. Searching new takes longer each time. More exactly, the number of
comparisons should be about len(s)*len(new_final)/2, depending on how
duplicates are distributed in s.

Jun 27 '08 #19
"Thomas Bellman" <be*****@lysator.liu.sewrote in message
news:g0**********@news.lysator.liu.se...
"John Salerno" <jo******@NOSPAMgmail.comwrites:
>"Diez B. Roggisch" <de***@nospam.web.dewrote in message
news:69*************@mid.uni-berlin.de...
>>the above code is pretty much of a no-no because it has quadratic
runtime
behavior.
>What's that mean, exactly?
However, it actually depends on what your input is. For the
runtime to increase with the square of the input length in your
function, the number of *unique* items on the input must be a
constant fraction of the input length.
Whew! Let me re-read your post........... :)
Jun 27 '08 #20
On May 20, 3:58 pm, Paul McGuire <pt...@austin.rr.comwrote:
On May 20, 8:13 am, "John Salerno" <johnj...@NOSPAMgmail.comwrote:
I posted this code last night in response to another thread, and after I
posted it I got to wondering if I had misused the list comprehension. Here's
the two examples:
Example 1:
--------------------
def compress(s):
new = []
for c in s:
if c not in new:
new.append(c)
return ''.join(new)
----------------------
Example 2:
------------------------
def compress(s):
new = []
[new.append(c) for c in s if c not in new]
return ''.join(new)
--------------------------
In example 1, the intention to make an in-place change is explicit, and it's
being used as everyone expects it to be used. In example 2, however, I began
to think this might be an abuse of list comprehensions, because I'm not
assigning the result to anything (nor am I even using the result in any
way).
What does everyone think about this? Should list comprehensions be used this
way, or should they only be used to actually create a new list that will
then be assigned to a variable/returned/etc.?

Why not make the list comp the actual list you are trying to build?
.... Because it obscures the intent of the code.

- Paddy.
Jun 27 '08 #21
On May 20, 11:08*am, Paul Hankin <paul.han...@gmail.comwrote:
On May 20, 3:58 pm, Paul McGuire <pt...@austin.rr.comwrote:
def compress(s):
* * seen = set()
* * return ''.join(c for c in s if c not in seen and (seen.add(c) or
True))

Slightly nicer is to move the set add out of the conditional...

def compress(s):
* * seen = set()
* * return ''.join(seen.add(c) or c for c in s if c not in seen)

I wouldn't write it this way though :)

--
Paul Hankin
Thank you, Paul. I knew I had seen a cleaner version than mine, and I
could not remember how it was done.

-- Paul
Jun 27 '08 #22
John Salerno wrote:
I posted this code last night in response to another thread, and after I
posted it I got to wondering if I had misused the list comprehension. Here's
the two examples:

Example 1:
--------------------
def compress(s):
new = []

for c in s:
if c not in new:
new.append(c)
return ''.join(new)
----------------------

Example 2:
------------------------
def compress(s):
new = []
[new.append(c) for c in s if c not in new]
return ''.join(new)
--------------------------

In example 1, the intention to make an in-place change is explicit, and it's
being used as everyone expects it to be used. In example 2, however, I began
to think this might be an abuse of list comprehensions, because I'm not
assigning the result to anything (nor am I even using the result in any
way).

What does everyone think about this? Should list comprehensions be used this
way, or should they only be used to actually create a new list that will
then be assigned to a variable/returned/etc.?

You might use this:

def compress(s)
return ''.join([ u for u in s if u not in locals()['_[1]'] ])
Jun 27 '08 #23
John Salerno wrote:
I posted this code last night in response to another thread, and after I
posted it I got to wondering if I had misused the list comprehension. Here's
the two examples:

Example 1:
--------------------
def compress(s):
new = []

for c in s:
if c not in new:
new.append(c)
return ''.join(new)
----------------------

Example 2:
------------------------
def compress(s):
new = []
[new.append(c) for c in s if c not in new]
return ''.join(new)
--------------------------

In example 1, the intention to make an in-place change is explicit, and it's
being used as everyone expects it to be used. In example 2, however, I began
to think this might be an abuse of list comprehensions, because I'm not
assigning the result to anything (nor am I even using the result in any
way).

What does everyone think about this? Should list comprehensions be used this
way, or should they only be used to actually create a new list that will
then be assigned to a variable/returned/etc.?

Alternative ways of of looking at the
problem are:

# compress.py
import sets

def compress(s):
new = []
[new.append(c) for c in s if c not
in new]
return ''.join(new)

def compress1(s):
new= []
d= dict(zip(s, len(s)*[[]]))
return d.keys()

def compress2(st):
s= sets.Set(st)
return s

if __name__ == "__main__":
s= 'In example 1, the intention to
make an in-place change is explicit, and
it is'
print (compress(s))
print (compress1(s))
print (compress2(s))

Results:

In exampl1,thiok-cgsd
['a', ' ', 'c', 'e', 'i', 'g', 'I', 'h',
'k', '-', 'm', 'l', 'o', 'n', '1', 'p',
's', 't', 'x', ',', 'd']
Set(['a', ' ', 'c', 'e', 'i', 'g', 'I',
'h', 'k', '-', 'm', 'l', 'o', 'n', '1',
'p', 's', 't', 'x', ',', 'd'])

Colin W.
Jun 27 '08 #24
Colin J. Williams wrote:
John Salerno wrote:
>I posted this code last night in response to another thread, and after
I posted it I got to wondering if I had misused the list
comprehension. Here's the two examples:

Example 1:
--------------------
def compress(s):
new = []

for c in s:
if c not in new:
new.append(c)
return ''.join(new)
----------------------

Example 2:
------------------------
def compress(s):
new = []
[new.append(c) for c in s if c not in new]
return ''.join(new)
--------------------------

In example 1, the intention to make an in-place change is explicit,
and it's being used as everyone expects it to be used. In example 2,
however, I began to think this might be an abuse of list
comprehensions, because I'm not assigning the result to anything (nor
am I even using the result in any way).

What does everyone think about this? Should list comprehensions be
used this way, or should they only be used to actually create a new
list that will then be assigned to a variable/returned/etc.?

Alternative ways of of looking at the problem are:

# compress.py
import sets

def compress(s):
new = []
[new.append(c) for c in s if c not in new]
return ''.join(new)

def compress1(s):
new= []
d= dict(zip(s, len(s)*[[]]))
return d.keys()

def compress2(st):
s= sets.Set(st)
return s

if __name__ == "__main__":
s= 'In example 1, the intention to make an in-place change is
explicit, and it is'
print (compress(s))
print (compress1(s))
print (compress2(s))

Results:

In exampl1,thiok-cgsd
['a', ' ', 'c', 'e', 'i', 'g', 'I', 'h', 'k', '-', 'm', 'l', 'o', 'n',
'1', 'p', 's', 't', 'x', ',', 'd']
Set(['a', ' ', 'c', 'e', 'i', 'g', 'I', 'h', 'k', '-', 'm', 'l', 'o',
'n', '1', 'p', 's', 't', 'x', ',', 'd'])

Colin W.
I should have read all the responses
before responding!

Paul McGuire had already suggested a set
approach

Colin W.
Jun 27 '08 #25
''.join(seen.add(c) or c for c in s if c not in seen)

From what I can understand...

..join will be a String of unique 'c' values.

'seen.add(c) or c' will always point to the second statement 'c'
because seen.add(c) returns None.

'if c not in seen' will ensure 'c' being added to both the .join and
seen is unique.

That is really clever! I like it :) (but does require a bit of
knowledge about .add return None and the affect that has on the ..
or .. statement)
Jun 27 '08 #26
On Tue, May 20, 2008 at 11:19 AM, John Salerno <jo******@nospamgmail.comwrote:
"Diez B. Roggisch" <de***@nospam.web.dewrote in message
news:69*************@mid.uni-berlin.de...
>After being corrected about missing the construction of a None-containing
list, one needs of course to think about the waste of resources, as a
possible result-list is created in any case.

Yeah, I was already aware of the list of Nones, which is why I asked. Simply
typing the list comprehension without an assignment just *looked* wrong,
too.
It sounds like the wasteful list creation is the biggest objection to
using a list comprehension. I'm curious what people think of this
alternative, which avoids populating the list by using a generator
expression instead (apart from the fact that this is still quadratic,
which I'm aware of).

def compress(s):
new = []
filter(None, (new.append(c) for c in s if c not in new))
return ''.join(new)
Jun 27 '08 #27
"Ian Kelly" <ia*********@gmail.comwrites:
On Tue, May 20, 2008 at 11:19 AM, John Salerno <jo******@nospamgmail.comwrote:
>"Diez B. Roggisch" <de***@nospam.web.dewrote in message
news:69*************@mid.uni-berlin.de...
>>After being corrected about missing the construction of a None-containing
list, one needs of course to think about the waste of resources, as a
possible result-list is created in any case.

Yeah, I was already aware of the list of Nones, which is why I asked. Simply
typing the list comprehension without an assignment just *looked* wrong,
too.

It sounds like the wasteful list creation is the biggest objection to
using a list comprehension. I'm curious what people think of this
alternative, which avoids populating the list by using a generator
expression instead (apart from the fact that this is still quadratic,
which I'm aware of).

def compress(s):
new = []
filter(None, (new.append(c) for c in s if c not in new))
return ''.join(new)
This is crazy!

--
Arnaud
Jun 27 '08 #28
On May 27, 6:43 pm, "Ian Kelly" <ian.g.ke...@gmail.comwrote:
On Tue, May 20, 2008 at 11:19 AM, John Salerno <johnj...@nospamgmail.comwrote:
"Diez B. Roggisch" <de...@nospam.web.dewrote in message
news:69*************@mid.uni-berlin.de...
After being corrected about missing the construction of a None-containing
list, one needs of course to think about the waste of resources, as a
possible result-list is created in any case.
Yeah, I was already aware of the list of Nones, which is why I asked. Simply
typing the list comprehension without an assignment just *looked* wrong,
too.

It sounds like the wasteful list creation is the biggest objection to
using a list comprehension. I'm curious what people think of this
alternative, which avoids populating the list by using a generator
expression instead (apart from the fact that this is still quadratic,
which I'm aware of).

def compress(s):
new = []
filter(None, (new.append(c) for c in s if c not in new))
return ''.join(new)
It could be shorter:

def compress(s):
new = []
return filter(None, (new.append(c) for c in s if c not in new)) or
''.join(new)

:-)
Jun 27 '08 #29
En Tue, 27 May 2008 14:43:52 -0300, Ian Kelly <ia*********@gmail.com>
escribió:
It sounds like the wasteful list creation is the biggest objection to
using a list comprehension. I'm curious what people think of this
alternative, which avoids populating the list by using a generator
expression instead (apart from the fact that this is still quadratic,
which I'm aware of).

def compress(s):
new = []
filter(None, (new.append(c) for c in s if c not in new))
return ''.join(new)
filter returns a newly created list, so this code is as wasteful as a list
comprehension (and harder to read).

--
Gabriel Genellina

Jun 27 '08 #30
On Tue, May 27, 2008 at 8:08 PM, Gabriel Genellina
<ga*******@yahoo.com.arwrote:
En Tue, 27 May 2008 14:43:52 -0300, Ian Kelly <ia*********@gmail.com>
escribió:
>It sounds like the wasteful list creation is the biggest objection to
using a list comprehension. I'm curious what people think of this
alternative, which avoids populating the list by using a generator
expression instead (apart from the fact that this is still quadratic,
which I'm aware of).

def compress(s):
new = []
filter(None, (new.append(c) for c in s if c not in new))
return ''.join(new)

filter returns a newly created list, so this code is as wasteful as a list
comprehension (and harder to read).
Here it returns a newly created *empty* list, which is not nearly as
wasteful as one that's linear in the size of the input. I'll grant
you the second point, though. I very much doubt that I would ever
actually use this myself. I was just curious what others would think
of it.
Jun 27 '08 #31
Lie
On May 20, 8:51*pm, "Diez B. Roggisch" <de...@nospam.web.dewrote:
bearophileH...@lycos.com wrote:
John Salerno:
What does everyone think about this?
The Example 2 builds a list, that is then thrown away. It's just a
waste of memory (and time).

No, it doesn't. It uses append because it refers to itself in the
if-expression. So the append(c) is needed - and thus the assignment
possible but essentially useless.

Diez
Yes it does, it build a list of 'None's.

And if list.append is concerned, the example given has no use, since:
x = [c for c in cs]
is essentially the same as
x = []
[x.append(c) for c in cs]

If, you're talking about other function calls, it might be an abuse or
not depending on personal preference.
Jun 27 '08 #32

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Elaine Jackson | last post: by
24 posts views Thread by Mahesh Padmanabhan | last post: by
9 posts views Thread by Neuruss | last post: by
42 posts views Thread by Alan McIntyre | last post: by
30 posts views Thread by Steven Bethard | last post: by
6 posts views Thread by Lonnie Princehouse | last post: by
reply views Thread by Delaney, Timothy (Tim) | last post: by
reply views Thread by Ian Kelly | last post: by
reply views Thread by NPC403 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.