beginner, idiomatic python

B

bambam

Would someone like to suggest a replacement for this? It works ok,
but it doesn't look like any of the other code:

tempList = ['1','2','3','4','5','6','7','8']
sampleList=[]
for port in tempList:
pagefound = False
for i in range(self.parent.GetPageCount()):
page=self.parent.GetPage(i)
if hasattr(page, "port"):
if page.port == int(port):
pagefound=True
if not pagefound:
sampleList.append(port)

Thanks!
 
S

Scott David Daniels

bambam said:
Would someone like to suggest a replacement for this? It works ok,
but it doesn't look like any of the other code:

tempList = ['1','2','3','4','5','6','7','8']
sampleList=[]
for port in tempList:
pagefound = False
for i in range(self.parent.GetPageCount()):
page=self.parent.GetPage(i)
if hasattr(page, "port"):
if page.port == int(port):
pagefound=True
if not pagefound:
sampleList.append(port)

Thanks!
Look at good questions. This is a _very_ underspecified question.

One stab at mindreading:

def ported_pages(self):
for i in range(self.parent.GetPageCount()):
if hasattr(page, 'port'):
yield page

...
tempList = ['1','2','3','4','5','6','7','8']
missing = dict((int(v), v) for v in tempList)
for page in self.ported_pages():
if page.port in missing:
missing.pop(page.port)
if not missing:
break
sampleList = missing.values()
...

-Scott David Daniels
 
Z

Zentrader

Does page count change? i.e. is it necessary to retrieve it in every
loop or
tempList = ['1','2','3','4','5','6','7','8']
sampleList=[]
page_count = self.parent.GetPageCount()
<snipped>
for i in range(page_count):

Also, once pagefound is set to True, all pages following will not be
appended to sampleList because it is not initialized to False under
the "for i in range(self.parent.GetPageCount())" loop.

Finally, if I understand the logic and question correctly, you want
something like
tempList = ['1','2','3','4','5','6','7','8']
sampleList=[]
page_count = self.parent.GetPageCount()
for port in tempList:
for i in range(page_count):
page=self.parent.GetPage(i)
if (hasattr(page, "port")) and (page.port != int(port)) :
sampleList.append(port)

or perhaps (I'm not sure)
tempList = [1, 2, 3, 4, 5, 6, 7, 8]
sampleList=[]
page_count = self.parent.GetPageCount()
for i in range(page_count):
page=self.parent.GetPage(i)
if (hasattr(page, "port")) and (page.port not in tempList) :
sampleList.append(port)
HTH
 
B

bambam

Wos! Several different thoughts:

An object using yield to return only the relevant pages, one at a time.
Pop to remove the items from the list.
A dictionary to map between the strings and the integers.

The dictionary was particularly unexpected. Eventually, I
plan to change the string ports to device names. On the other
hand, it looks like the only reason I have port numbers is
to use as an index in things like this.

After examining your suggestion, I realised that another thing
I am interested in could be generalised: I want the complement
of the set of ports in pages, given a universal set in tempList.
Ignoring the break condition for the moment, and my problem
with int(port)/str(port), would you have offered a different solution
if I had asked for the relative complement of a small set?

a= ['a','b','c']
b= ['b']
c= a-b #set theoretic difference, a\b, a.~b, ['a','c']

Steve.
 
G

Gabriel Genellina

After examining your suggestion, I realised that another thing
I am interested in could be generalised: I want the complement
of the set of ports in pages, given a universal set in tempList.
Ignoring the break condition for the moment, and my problem
with int(port)/str(port), would you have offered a different solution
if I had asked for the relative complement of a small set?

a= ['a','b','c']
b= ['b']
c= a-b #set theoretic difference, a\b, a.~b, ['a','c']

If you want a set - just use a set:

py> a = set(['a','b','c'])
py> b = set(['b'])
py> c = a-b
py> c
set(['a', 'c'])
 
B

bambam

Thank you, so generallizing:

(1) Python re-evaluates the loop range on every loop, and
(2) Python does short-circuit evaluation of conditions, in predictable
order.

Sorry about the bad question.
 
B

bambam

Wos! Several different thoughts:

An object using yield to return only the relevant pages, one at a time.
Pop to remove the items from the list.
A dictionary to map between the strings and the integers.

The dictionary was particularly unexpected. Eventually, I
plan to change the string ports to device names. On the other
hand, it looks like the only reason I have port numbers is
to use as an index in things like this.

After examining your suggestion, I realised that another thing
I am interested in could be generalised: I want the complement
of the set of ports in pages, given a universal set in tempList.
Ignoring the break condition for the moment, and my problem
with int(port)/str(port), would you have offered a different solution
if I had asked for the relative complement of a small set?

a= ['a','b','c']
b= ['b']
c= a-b #set theoretic difference, a\b, a.~b, ['a','c']

Steve.

Scott David Daniels said:
bambam said:
Would someone like to suggest a replacement for this? It works ok,
but it doesn't look like any of the other code:

tempList = ['1','2','3','4','5','6','7','8']
sampleList=[]
for port in tempList:
pagefound = False
for i in range(self.parent.GetPageCount()):
page=self.parent.GetPage(i)
if hasattr(page, "port"):
if page.port == int(port):
pagefound=True
if not pagefound:
sampleList.append(port)

Thanks!
Look at good questions. This is a _very_ underspecified question.

One stab at mindreading:

def ported_pages(self):
for i in range(self.parent.GetPageCount()):
if hasattr(page, 'port'):
yield page

...
tempList = ['1','2','3','4','5','6','7','8']
missing = dict((int(v), v) for v in tempList)
for page in self.ported_pages():
if page.port in missing:
missing.pop(page.port)
if not missing:
break
sampleList = missing.values()
...

-Scott David Daniels
 
B

bambam

Excellent. By symmetry, I see that "list" casts the set back into a list.

I wonder why list has not been extended with the same (difference,
interesection) methods? Casting to set looks a little kludgy:

c = list(set(a)-set(b))

I wonder if that is clearer than the explicit loop?

Steve.

Gabriel Genellina said:
After examining your suggestion, I realised that another thing
I am interested in could be generalised: I want the complement
of the set of ports in pages, given a universal set in tempList.
Ignoring the break condition for the moment, and my problem
with int(port)/str(port), would you have offered a different solution
if I had asked for the relative complement of a small set?

a= ['a','b','c']
b= ['b']
c= a-b #set theoretic difference, a\b, a.~b, ['a','c']

If you want a set - just use a set:

py> a = set(['a','b','c'])
py> b = set(['b'])
py> c = a-b
py> c
set(['a', 'c'])
 
E

Erik Max Francis

bambam said:
Excellent. By symmetry, I see that "list" casts the set back into a list.

I wonder why list has not been extended with the same (difference,
interesection) methods? Casting to set looks a little kludgy:

c = list(set(a)-set(b))
I wonder if that is clearer than the explicit loop?

This isn't a "cast" in the sense of some less-strongly-typed languages;
it's just a conversion. The `list` function/type iterates over its
argument and turns it into a list. Sets are iterable, so that's all
that's really going on here.

The reason that lists don't have set-like methods is because lists
aren't sets -- lists can contain duplicate elements, whereas sets
cannot. You should use the proper type for your needs; if you want to
take two lists, remove duplicate elements, and then end up with a list,
then the sets-difference-and-then-make-a-list mechanism is appropriate.
 
B

bambam

This isn't a "cast" in the sense of some less-strongly-typed languages;
it's just a conversion. The `list` function/type iterates over its
argument and turns it into a list. Sets are iterable, so that's all
that's really going on here.

oh :~). Learning experience happening here... Thank you.
The reason that lists don't have set-like methods is because
lists aren't sets -- lists can contain duplicate elements

Interesting point -- if that's all there is in it, then lists should
have difference and intersection methods. Not because they
are the same as sets -- because they are slightly different than
sets. 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.
Still, any built in feature would probably be too simple to
use in any but the simplest cases.

Steve.



Erik Max Francis said:
bambam said:
Excellent. By symmetry, I see that "list" casts the set back into a list.

I wonder why list has not been extended with the same (difference,
interesection) methods? Casting to set looks a little kludgy:

c = list(set(a)-set(b))
I wonder if that is clearer than the explicit loop?

This isn't a "cast" in the sense of some less-strongly-typed languages;
it's just a conversion. The `list` function/type iterates over its
argument and turns it into a list. Sets are iterable, so that's all
that's really going on here.

The reason that lists don't have set-like methods is because lists aren't
sets -- lists can contain duplicate elements, whereas sets cannot. You
should use the proper type for your needs; if you want to take two lists,
remove duplicate elements, and then end up with a list, then the
sets-difference-and-then-make-a-list mechanism is appropriate.

--
Erik Max Francis && (e-mail address removed) && http://www.alcyone.com/max/
San Jose, CA, USA && 37 20 N 121 53 W && AIM, Y!M erikmaxfrancis
It [freedom] must be demanded by the oppressed.
-- Dr. Martin Luther King, Jr.
 
M

Mikael Olofsson

bambam 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
 
S

Scott David Daniels

and they are ordered. I'd have used sets if I was sure you
meant [1,2,3] to mean the same thing as [3,1,2] and no duplicates.
Interesting point -- if that's all there is in it, then lists should
have difference and intersection methods. Not because they
are the same as sets -- because they are slightly different than
sets. 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.
Here you seem to be talking about multisets (also called bags).
They have more fully defined algebraic properties analogous to sets.

bag([1,2,3,3,4]) == bag([3,1,2,4,3]) != bag([1,2,3,4])
bag([1,2,2,3]) - bag([1,2]) == bag([2,3])
bag([1,2,3]) - bag([3,4]) == bag([1])
Some will say 'sorted' is a better conversion of a set to list, since
the result is well-defined.

--Scott David Daniels
(e-mail address removed)
 
P

Paul McGuire

Thank you, so generallizing:

(1) Python re-evaluates the loop range on every loop, and
(2) Python does short-circuit evaluation of conditions, in predictable
order.

Sorry about the bad question.

A beginner would do well to work through the Python Tutorial (http://
docs.python.org/tut/tut.html). I think your first "insight" is
actually incorrect, if I understand your wording. If I wrote:

for i in range(1000000000):
# do something with i

I'm quite certain that range(1000000000) is not evaluated on every
loop iteration. In fact, the range call generates a list containing
the values [0, 1, 2, ..., 999999999], and then for iterates over this
list. You can read this at http://docs.python.org/tut/node6.html#SECTION006300000000000000000.

On the other hand, if you are talking about a while loop, of course
the condition is evaluated on every loop - otherwise such a loop, once
entered, would never exit.

Your second generalization is stated pretty plainly in
http://docs.python.org/tut/node7.html#SECTION007700000000000000000.
In fact, conditional short-circuiting is a consistent theme in most
Python functions and structures. The new any() and all() built-ins in
Python 2.5 for example, evaluate a list of values for their boolean
True/False-ness, any() returning True if any list entry is True,
otherwise False; and all() returning True if all entries are True,
otherwise False. Both short-circuit their evaluation, so that if the
first element of a billion element list gives a True value for any()
(or a False value for all()), then the evaluation of the remaining
billion-1 items is skipped.

Best of luck in your new Python learning process,
-- Paul
 
B

bambam

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
 
B

bambam

c = sorted(set(a)-set(b))

although for me :~( that is another step more obscure than

c = list(set(a)-set(b))
c.sort()

Bags don't seem to be built in to my copy of Python, and
although I'm interested in why lists don't support the difference
operation, I don't want to get away from standard Python.

Steve.

Scott David Daniels said:
and they are ordered. I'd have used sets if I was sure you
meant [1,2,3] to mean the same thing as [3,1,2] and no duplicates.
Interesting point -- if that's all there is in it, then lists should
have difference and intersection methods. Not because they
are the same as sets -- because they are slightly different than
sets. 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.
Here you seem to be talking about multisets (also called bags).
They have more fully defined algebraic properties analogous to sets.

bag([1,2,3,3,4]) == bag([3,1,2,4,3]) != bag([1,2,3,4])
bag([1,2,2,3]) - bag([1,2]) == bag([2,3])
bag([1,2,3]) - bag([3,4]) == bag([1])
Some will say 'sorted' is a better conversion of a set to list, since
the result is well-defined.

--Scott David Daniels
(e-mail address removed)
 
B

bambam

Ok, many environments are capable of cached evaluation
of functions without variable parameters so
range(5)
is cached, but
range(v) is re-evaluated every time. Is this defined
behaviour?

That is, is it defined what Python does for
for i in f()
I'm sure it must be, but I haven't seen it yet. If I have
a user defined function returning a range, is it defined
that the range function is called on every loop? If I
have a function returning a range taking a parameter,
for i in f(v)
is it defined that the variable is evaluated for every loop?

Steve.


Paul McGuire said:
Thank you, so generallizing:

(1) Python re-evaluates the loop range on every loop, and
(2) Python does short-circuit evaluation of conditions, in predictable
order.

Sorry about the bad question.

A beginner would do well to work through the Python Tutorial (http://
docs.python.org/tut/tut.html). I think your first "insight" is
actually incorrect, if I understand your wording. If I wrote:

for i in range(1000000000):
# do something with i

I'm quite certain that range(1000000000) is not evaluated on every
loop iteration. In fact, the range call generates a list containing
the values [0, 1, 2, ..., 999999999], and then for iterates over this
list. You can read this at
http://docs.python.org/tut/node6.html#SECTION006300000000000000000.

On the other hand, if you are talking about a while loop, of course
the condition is evaluated on every loop - otherwise such a loop, once
entered, would never exit.

Your second generalization is stated pretty plainly in
http://docs.python.org/tut/node7.html#SECTION007700000000000000000.
In fact, conditional short-circuiting is a consistent theme in most
Python functions and structures. The new any() and all() built-ins in
Python 2.5 for example, evaluate a list of values for their boolean
True/False-ness, any() returning True if any list entry is True,
otherwise False; and all() returning True if all entries are True,
otherwise False. Both short-circuit their evaluation, so that if the
first element of a billion element list gives a True value for any()
(or a False value for all()), then the evaluation of the remaining
billion-1 items is skipped.

Best of luck in your new Python learning process,
-- Paul
 
G

Gabriel Genellina

Ok, many environments are capable of cached evaluation
of functions without variable parameters so
range(5)
is cached, but
range(v) is re-evaluated every time. Is this defined
behaviour?

The range builtin function returns a list, and lists are mutable objects,
so it must return a *different* list each time.
That is, is it defined what Python does for
for i in f()
I'm sure it must be, but I haven't seen it yet. If I have
a user defined function returning a range, is it defined
that the range function is called on every loop? If I
have a function returning a range taking a parameter,
for i in f(v)
is it defined that the variable is evaluated for every loop?

Find all the (mostly negative) answers yourself in
<http://docs.python.org/ref/for.html>
 
S

Scott David Daniels

bambam said:
That is, is it defined what Python does for
for i in f()
I'm sure it must be, but I haven't seen it yet. If I have
a user defined function returning a range, is it defined
that the range function is called on every loop? If I
have a function returning a range taking a parameter,
for i in f(v)
is it defined that the variable is evaluated for every loop?

Nope. Take the tutorial.

for i in f(v):
<suite>
is the same as:
iterator = iter(f(v))
for i in iterator:
<suite>

-Scott David Daniels
(e-mail address removed)
 
B

bambam

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:
Does page count change? i.e. is it necessary to retrieve it in every loop


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

Steve.
 
B

bambam

Thank you, I have been through the tutorial several times, I guess
I'm just not smart enough. Python is quite different from the
languages I am familiar with.

My code sample started like this:

I was asked:
Does page count change? i.e. is it necessary to retrieve it in every loop


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

Steve.
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top