Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #43675 > unrolled thread

a couple of things I don't understand wrt lists

Started byaaB <mecagonoisician@gmail.com>
First post2013-04-16 17:37 +0200
Last post2013-04-17 09:10 -0700
Articles 9 — 8 participants

Back to article view | Back to comp.lang.python


Contents

  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

#43675 — a couple of things I don't understand wrt lists

FromaaB <mecagonoisician@gmail.com>
Date2013-04-16 17:37 +0200
Subjecta 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]


#43682

FromJohn Gordon <gordon@panix.com>
Date2013-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]


#43728

FromLarry Hudson <orgnut@yahoo.com>
Date2013-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]


#43751

FromSerhiy Storchaka <storchaka@gmail.com>
Date2013-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]


#43766

From88888 Dihedral <dihedral88888@googlemail.com>
Date2013-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]


#43772

FromNed Batchelder <ned@nedbatchelder.com>
Date2013-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]


#43775

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-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]


#43773

FromChris Angelico <rosuav@gmail.com>
Date2013-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]


#43767

From88888 Dihedral <dihedral88888@googlemail.com>
Date2013-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