473,748 Members | 2,239 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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 1222
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
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 #6
Thomas Bellman wrote:
"Diez B. Roggisch" <de***@nospam.w eb.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 #7
On May 20, 8:13*am, "John Salerno" <johnj...@NOSPA Mgmail.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 #8
Paul McGuire <pt***@austin.r r.comwrites:
On May 20, 8:13*am, "John Salerno" <johnj...@NOSPA Mgmail.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 #9
On May 20, 9:58 am, Paul McGuire <pt...@austin.r r.comwrote:
On May 20, 8:13 am, "John Salerno" <johnj...@NOSPA Mgmail.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 #10

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

Similar topics

2
1635
by: Elaine Jackson | last post by:
List comprehensions don't work the way you intuitively expect them to work. I realize many people have no intuitions about how list comprehensions 'should' work, so if you recognize yourself in this description, feel free to go back to whatever you were doing before. If you're still here, though, I invite you to consider the following definition: partitions = lambda n: ]++x for x in partitions(n-k) for k in range(1,n)] As defined...
24
3351
by: Mahesh Padmanabhan | last post by:
Hi, When list comprehension was added to the language, I had a lot of trouble understanding it but now that I am familiar with it, I am not sure how I programmed in Python without it. Now I see that generator expressions have been added to the language with 2.4 and I question the need for it. I know that it allows for lazy evaluation which speeds things up for larger lists but why was it necessary to add it instead of improving list...
9
2357
by: Neuruss | last post by:
I have a doubt regarding list comprehensions: According to Mark Lutz in his book Learning Pyhon: "...there is currently a substantial performance advantage to the extra complexity in this case: based on tests run under Python 2.2, map calls are roughly twice as fast as equivalent for loops, and list comprehensions are usually very slightly faster than map. This speed difference owes to the fact that map and list comprehensions run at C...
42
2619
by: Alan McIntyre | last post by:
Hi all, I have a list of items that has contiguous repetitions of values, but the number and location of the repetitions is not important, so I just need to strip them out. For example, if my original list is , I want to end up with . Here is the way I'm doing this now: def straightforward_collapse(myList):
23
2271
by: Mike Meyer | last post by:
Ok, we've added list comprehensions to the language, and seen that they were good. We've added generator expressions to the language, and seen that they were good as well. I'm left a bit confused, though - when would I use a list comp instead of a generator expression if I'm going to require 2.4 anyway? Thanks, <mike --
30
3473
by: Steven Bethard | last post by:
George Sakkis wrote: > "Steven Bethard" <steven.bethard@gmail.com> wrote: >> Dict comprehensions were recently rejected: >> http://www.python.org/peps/pep-0274.html >> The reason, of course, is that dict comprehensions don't gain you >> much at all over the dict() constructor plus a generator expression, >> e.g.: >> dict((i, chr(65+i)) for i in range(4)) > > Sure, but the same holds for list comprehensions: list(i*i for i in
6
1400
by: Lonnie Princehouse | last post by:
List comprehensions appear to store their temporary result in a variable named "_" (or presumably "_", "_" etc for nested comprehensions) In other words, there are variables being put into the namespace with illegal names (names can't contain brackets). Can't someone come up with a better hack than this? How about using "_1", "_2", etc, or actually making "_" a list of lists and using the real first, second, third elements? This is...
0
683
by: Delaney, Timothy (Tim) | last post by:
Ian Kelly wrote: Are you aware that filter() returns a list populated from its arguments? Tim Delaney
0
727
by: Ian Kelly | last post by:
On Tue, May 27, 2008 at 7:09 PM, Delaney, Timothy (Tim) <tdelaney@avaya.comwrote: Yes. In this case, it returns an empty list.
0
9372
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9324
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9247
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6796
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 presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6074
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 then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4874
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3313
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2783
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2215
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 can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.