beginner, idiomatic python

B

bambam

Is it safe to write

A = [x for x in A if x in U]

or is that undefined? I understand that the slice operation
can be used to make a temporary copy, so I could write

A=[x for x in A[:] if x in U]

but I've just copied that without any understanding.

Steve.


bambam said:
That looks good, and perhaps a difference operator
would be too simple to be useful anyway.

Steve.

Mikael Olofsson said:
In this case it doesn't matter - my lists don't contain
duplicate elements this time - but I have worked with lists in
money market and in inventory, and finding the intersection
and difference for matching off and netting out are standard
operations.

I would use a list comprehension for that case:

A = ['a','b','c','a','c','d']
U = ['a','b','e']
B = [x for x in A if x in U]

The result would be B==['a','b','a']

/MiO
 
A

Alex Martelli

bambam said:
Is it safe to write

A = [x for x in A if x in U]

or is that undefined? I understand that the slice operation

It's perfectly safe and well-defined, as the assignment rebinds the LHS
name only AFTER the RHS list comprehension is done.


Alex
 
A

Alex Martelli

bambam said:
Bags don't seem to be built in to my copy of Python, and

A "bag" is a collections.defaultdict(int) [[you do have to import
collections -- it's in the standard library, NOT built-in]].


Alex
 
P

Paul Rubin

bambam said:
Is it safe to write
A = [x for x in A if x in U]
or is that undefined? I understand that the slice operation
can be used to make a temporary copy, so I could write
A=[x for x in A[:] if x in U]
but I've just copied that without any understanding.

You get a temporary copy either way; note you're going to linearly
search U on every pass. Maybe you want:

SU = set(u)
A = [a for x in A if x in SU]

or possibly

A = list(set(A) & set(U))

which will remove duplicate elements from A and not necessarily keep
them in the same order, but is likely to be fastest of the bunch.
 
B

bambam

Thank you.

Steve.

Alex Martelli said:
bambam said:
Is it safe to write

A = [x for x in A if x in U]

or is that undefined? I understand that the slice operation

It's perfectly safe and well-defined, as the assignment rebinds the LHS
name only AFTER the RHS list comprehension is done.


Alex
 
B

bambam

Thank you. I figured the set would probably be faster,
but the lists are small, and I'm concerned that the code
is going to look Byzantine if I keep swapping between
lists, sets and dictionaries :~).

At the moment there are no sets or dictionaries in the
entire code base I am working with. I'm not sure if the
place I am looking at right now is supposed to support
duplicates or not: duplicates are permitted, but they
cause report anomalies.

Steve.


Paul Rubin said:
bambam said:
Is it safe to write
A = [x for x in A if x in U]
or is that undefined? I understand that the slice operation
can be used to make a temporary copy, so I could write
A=[x for x in A[:] if x in U]
but I've just copied that without any understanding.

You get a temporary copy either way; note you're going to linearly
search U on every pass. Maybe you want:

SU = set(u)
A = [a for x in A if x in SU]

or possibly

A = list(set(A) & set(U))

which will remove duplicate elements from A and not necessarily keep
them in the same order, but is likely to be fastest of the bunch.
 
B

Bruno Desthuilliers

bambam a écrit :
Thank you, I have been through the tutorial several times, I guess
I'm just not smart enough. Perhaps I have been led astray by what
I read here?

My code started like this:

for i in range(self.parent.GetPageCount()):

I was asked:



Is self.parent.GetPageCount() 'retrieved every loop'?

If your question is 'is self.parent.GetPageCount()' called for each
iteration of this loop, then the answer is obviously 'no', and it's
quite easy to check it out:

Python 2.5.1 (r251:54863, May 2 2007, 16:56:35)
[GCC 4.1.2 (Ubuntu 4.1.2-0ubuntu4)] on linux2
Type "help", "copyright", "credits" or "license" for more information..... print "test called"
.... return range(5)
........
test called
0
1
2
3
4

Now if you need to use the result of self.parent.GetPageCount() more
than once in the same function and this result is not likely to change
during the function's execution, you're certainly better storing it in a
local variable - but now that's such a CS101 thing that it's probably
not even worth mentionning.

IOW, Zentrader's remark was at best misleading, at worst plain wrong...
 
N

Neil Cerutti

Thank you, I have been through the tutorial several times, I
guess I'm just not smart enough. Perhaps I have been led astray
by what I read here?

My code started like this:

for i in range(self.parent.GetPageCount()):

I was asked:


Is self.parent.GetPageCount() 'retrieved every loop'?

No. The question seems to imply that if you wish it to be
retrieved every loop you must change the code to something else.

i = 0
while i < self.parent.GetPageCount():
# do stuff
i += 1

I find that kind of while loop clunky. Since Python is
hard-headed about not providing a structured looping construct,
you may feel the need to compose your own special-purpose
iterator or generator instead.

def pageCountGenerator(document):
i = 0
while i < document.GetPageCount():
yield i
i += 1

It can be used like this:

for i in pageCountGenerator(self.parent):
# do stuff

That way you get the happy syntax of a for loop, with the
additional safety of checking the page count each iteration.

This sort of suggests a direct solution:

for i in xrange(self.parent.GetPageCount()):
if i >= self.parent.GetPageCount():
break
# do stuff

At least that way you're spared the manual manipulation of i.
 
N

Neil Cerutti

This sort of suggests a direct solution:

for i in xrange(self.parent.GetPageCount()):
if i >= self.parent.GetPageCount():
break
# do stuff

At least that way you're spared the manual manipulation of i.

On second thought, that last suggestion is flawed, as a growing
page count would be ignored. Please ignore.
 
P

Paul Rubin

Neil Cerutti said:
i = 0
while i < self.parent.GetPageCount():
# do stuff
i += 1

Alternatively:

from itertools import count

for i in count():
if i >= self.parent.GetPageCount():
break
...
 

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

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top