Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #43675 > unrolled thread
| Started by | aaB <mecagonoisician@gmail.com> |
|---|---|
| First post | 2013-04-16 17:37 +0200 |
| Last post | 2013-04-17 09:10 -0700 |
| Articles | 9 — 8 participants |
Back to article view | Back to comp.lang.python
a couple of things I don't understand wrt lists aaB <mecagonoisician@gmail.com> - 2013-04-16 17:37 +0200
Re: a couple of things I don't understand wrt lists John Gordon <gordon@panix.com> - 2013-04-16 16:43 +0000
Re: a couple of things I don't understand wrt lists Larry Hudson <orgnut@yahoo.com> - 2013-04-16 21:57 -0700
Re: a couple of things I don't understand wrt lists Serhiy Storchaka <storchaka@gmail.com> - 2013-04-17 12:35 +0300
Re: a couple of things I don't understand wrt lists 88888 Dihedral <dihedral88888@googlemail.com> - 2013-04-17 09:10 -0700
Re: a couple of things I don't understand wrt lists Ned Batchelder <ned@nedbatchelder.com> - 2013-04-17 14:36 -0400
Re: a couple of things I don't understand wrt lists Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-04-18 04:46 +1000
Re: a couple of things I don't understand wrt lists Chris Angelico <rosuav@gmail.com> - 2013-04-18 04:42 +1000
Re: a couple of things I don't understand wrt lists 88888 Dihedral <dihedral88888@googlemail.com> - 2013-04-17 09:10 -0700
| From | aaB <mecagonoisician@gmail.com> |
|---|---|
| Date | 2013-04-16 17:37 +0200 |
| Subject | a couple of things I don't understand wrt lists |
| Message-ID | <mailman.668.1366126626.3114.python-list@python.org> |
hello,
I am a beginner programmer. I started learning programming about a year and a
half ago, using C. I picked up python a few months ago, but only wrote very few
scripts.
I am currently trying to learn more about the python way of doing things by
writing a script that generates png images using a 1D cellular automaton.
While writing preliminary code for that project, I ran into a behaviour that I
don't understand.
I am using python 2.7 on a linux system.
I represent the CA's rule with a list of integers, of value 1 or 0.
Here is the function I use to generate the list:
def get_rule(rulenum):
rule = []
while rulenum > 0:
rule.append(rulenume % 2)
rulenum /= 2
while len(rule) < 8:
rule.append(0)
rule.reverse()
return rule
if i call it by writing:
rule = getrule(int(8))
and then call:
print rule
the output is good:
[0, 0, 0, 0, 1, 0, 0, 0]
I then tried to print each item of the list using a for loop:
for i in range(rule):
print rule[i]
the output is, as expected:
0
0
0
0
1
0
0
0
but when I do:
for i in rule:
print rule[i]
I get the "complement":
1
1
1
1
0
1
1
1
There must be something I didn't understand correctly in the for statement, but
I really can't think of a reason why the output is what it is.
I tried this using the interactive console, and the results are the same,
whatever the length of the list, i always get the complement of my bit pattern.
Any pointers to help me understand this would be appreciated.
I am also running into an other issue with this script, but I'd rather
understand this before asking further questions.
Thanks, and sorry for the rather long post.
[toc] | [next] | [standalone]
| From | John Gordon <gordon@panix.com> |
|---|---|
| Date | 2013-04-16 16:43 +0000 |
| Message-ID | <kkjv3b$9pj$1@reader1.panix.com> |
| In reply to | #43675 |
In <mailman.668.1366126626.3114.python-list@python.org> aaB <mecagonoisician@gmail.com> writes:
> but when I do:
> for i in rule:
> print rule[i]
> I get the "complement":
> 1
> 1
> 1
> 1
> 0
> 1
> 1
> 1
When you iterate over a list with this statement:
for i in rule:
i contains each successive list item.
However, your code:
print rule[i]
acts as though i is the list item's *subscript*, which is incorrect.
In effect, your code is doing this:
print rule[0]
print rule[0]
print rule[0]
print rule[0]
print rule[1]
print rule[0]
print rule[0]
print rule[0]
Although in your example both rule[0] and rule[1] are zero, so I
don't know why '1' ever got printed.
Also, as far as I can tell, this code should not have worked at all:
for i in range(rule):
print rule[i]
The range() function expects an integer, not a list.
--
John Gordon A is for Amy, who fell down the stairs
gordon@panix.com B is for Basil, assaulted by bears
-- Edward Gorey, "The Gashlycrumb Tinies"
[toc] | [prev] | [next] | [standalone]
| From | Larry Hudson <orgnut@yahoo.com> |
|---|---|
| Date | 2013-04-16 21:57 -0700 |
| Message-ID | <2rGdndNcINM-tvPMnZ2dnUVZ_jqdnZ2d@giganews.com> |
| In reply to | #43675 |
On 04/16/2013 08:37 AM, aaB wrote:
> hello,
>
<snip>
>
> I represent the CA's rule with a list of integers, of value 1 or 0.
> Here is the function I use to generate the list:
>
> def get_rule(rulenum):
> rule = []
> while rulenum > 0:
> rule.append(rulenume % 2)
> rulenum /= 2
> while len(rule) < 8:
> rule.append(0)
> rule.reverse()
> return rule
>
It appears what you are trying to do is create an eight-element list corresponding to the binary
value of rulenum. Here is a different approach, using some other functions and features of
Python...
First you can use the bin() function to get the binary value of an integer as a string. But
this string has a leading '0b', which can be cut off with slicing. eg. (using your example
value of 8 and bs as the variable name for the binary string)
bin(8) gives the string '0b1000', so slicing off the two leading characters:
bs = bin(8)[2:]
bs becomes the string '1000'
Now, the number of leading zeros needed is (8 - len(bs)). You can create the initial list of
leading zeros with the statement:
rule = [0] * (8 - len(bs)).
This gives rule as the list [0, 0, 0, 0].
Finally use a for loop to append the rest if the binary string as integers
for i in bs:
rule.append(int(i))
So your function becomes (with a few changed variable names):
def get_rule(num):
bs = bin(num)[2:]
rule = [0] * (8 - len(bs))
for i in bs:
rule.append(int(i))
return rule
This can be shortened even more with a list comprehension. You can think of a list
comprehension essentially as a terse variation of a for loop specifically to create a list.
So using a list comprehension you can do it in two lines:
def get_rule(num):
bs = bin(num)[2:]
return [0] * (8 - len(bs)) + [int(i) for i in bs]
Again, I'm assuming you specifically want an 8-element list. But this could easily be
generalized for any length by adding a second function parameter, say size, and change the 8 in
the last statement to size.
<snip>
> Any pointers to help me understand this would be appreciated.
> I am also running into an other issue with this script, but I'd rather
> understand this before asking further questions.
>
> Thanks, and sorry for the rather long post.
>
Don't worry about the length -- my reply is plenty wordy as well. I'm hoping I went into enough
detail that you can understand it without it being too advanced. Mainly I was just trying to
show you a different approach using other features of Python. There's nothing wrong with your
approach, it is quite straight-forward. In fact I used the same basic approach when I was
writing a C function to commify the display of integers -- that is, to add commas every third
digit.(*) Just about anything in programming can be approached in several different ways. I'm
not saying mine is better, and certainly not the best, just different. I'm not a newbie but FAR
from an expert. Keep learning Python, I think you'll like it.
(*)A special function for this isn't necessary in Python, it's already built in the the
new-style string formatting. Try this statement: '{:,}'.format(1000000)
(That's a colon and comma inside the curly braces.)
-=- Larry -=-
[toc] | [prev] | [next] | [standalone]
| From | Serhiy Storchaka <storchaka@gmail.com> |
|---|---|
| Date | 2013-04-17 12:35 +0300 |
| Message-ID | <mailman.718.1366191316.3114.python-list@python.org> |
| In reply to | #43728 |
17.04.13 07:57, Larry Hudson написав(ла):
> So using a list comprehension you can do it in two lines:
>
> def get_rule(num):
> bs = bin(num)[2:]
> return [0] * (8 - len(bs)) + [int(i) for i in bs]
You can do it in one line!
def get_rule(num):
return list(map(int, '{:08b}'.format(num)))
[toc] | [prev] | [next] | [standalone]
| From | 88888 Dihedral <dihedral88888@googlemail.com> |
|---|---|
| Date | 2013-04-17 09:10 -0700 |
| Message-ID | <2f8ccb0c-3fb5-4675-993a-4cd3d30dc3a1@googlegroups.com> |
| In reply to | #43751 |
Serhiy Storchaka於 2013年4月17日星期三UTC+8下午5時35分07秒寫道:
> 17.04.13 07:57, Larry Hudson написав(ла):
>
> > So using a list comprehension you can do it in two lines:
>
> >
>
> > def get_rule(num):
>
> > bs = bin(num)[2:]
>
> > return [0] * (8 - len(bs)) + [int(i) for i in bs]
>
>
>
> You can do it in one line!
>
>
>
> def get_rule(num):
>
> return list(map(int, '{:08b}'.format(num)))
Well, a new object is returned and can be used.
Then who is going to clean up the object when required?
[toc] | [prev] | [next] | [standalone]
| From | Ned Batchelder <ned@nedbatchelder.com> |
|---|---|
| Date | 2013-04-17 14:36 -0400 |
| Message-ID | <mailman.731.1366223819.3114.python-list@python.org> |
| In reply to | #43766 |
On 4/17/2013 12:10 PM, 88888 Dihedral wrote:
> Serhiy Storchaka於 2013年4月17日星期三UTC+8下午5時35分07秒寫道:
>> 17.04.13 07:57, Larry Hudson написав(ла):
>>
>>> So using a list comprehension you can do it in two lines:
>>> def get_rule(num):
>>> bs = bin(num)[2:]
>>> return [0] * (8 - len(bs)) + [int(i) for i in bs]
>>
>>
>> You can do it in one line!
>>
>>
>>
>> def get_rule(num):
>>
>> return list(map(int, '{:08b}'.format(num)))
> Well, a new object is returned and can be used.
> Then who is going to clean up the object when required?
This is a key thing to understand about Python: memory is managed
automatically, no one has to clean up the object. Once there are no
names referring to the object, it will be cleaned up automatically.
--Ned.
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2013-04-18 04:46 +1000 |
| Message-ID | <516eeddf$0$29971$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #43772 |
Ned Batchelder wrote: > On 4/17/2013 12:10 PM, 88888 Dihedral wrote: >> Well, a new object is returned and can be used. >> Then who is going to clean up the object when required? > > This is a key thing to understand about Python: memory is managed > automatically, no one has to clean up the object. Once there are no > names referring to the object, it will be cleaned up automatically. The key to understand about 88888 Dihedral is that it is a bot. :-) But seriously, it's a bot. -- Steven
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2013-04-18 04:42 +1000 |
| Message-ID | <mailman.732.1366224146.3114.python-list@python.org> |
| In reply to | #43766 |
On Thu, Apr 18, 2013 at 4:36 AM, Ned Batchelder <ned@nedbatchelder.com> wrote: > > On 4/17/2013 12:10 PM, 88888 Dihedral wrote: >> Well, a new object is returned and can be used. >> Then who is going to clean up the object when required? > > > This is a key thing to understand about Python: memory is managed > automatically, no one has to clean up the object. Once there are no names > referring to the object, it will be cleaned up automatically. Dihedral is a bot. An amusing one, at times, but not someone you need overly concern yourself with. :) ChrisA
[toc] | [prev] | [next] | [standalone]
| From | 88888 Dihedral <dihedral88888@googlemail.com> |
|---|---|
| Date | 2013-04-17 09:10 -0700 |
| Message-ID | <mailman.728.1366215818.3114.python-list@python.org> |
| In reply to | #43751 |
Serhiy Storchaka於 2013年4月17日星期三UTC+8下午5時35分07秒寫道:
> 17.04.13 07:57, Larry Hudson написав(ла):
>
> > So using a list comprehension you can do it in two lines:
>
> >
>
> > def get_rule(num):
>
> > bs = bin(num)[2:]
>
> > return [0] * (8 - len(bs)) + [int(i) for i in bs]
>
>
>
> You can do it in one line!
>
>
>
> def get_rule(num):
>
> return list(map(int, '{:08b}'.format(num)))
Well, a new object is returned and can be used.
Then who is going to clean up the object when required?
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web