[Tutor] Windows problem with large(?) files

2006-02-02 Thread johan nilsson
Dear group,I have a few files that contains data in IEEE 754 format. I need to transform them into a csv file, to be able to read these files in another program. Each file has 3 samples of I and Q. I did develop the attached script. I am sure not the best, but it worked at home on my Linux installation Python 
2.4. I was then very confident that it would work also on my work pc (XP with python 2.3). It does not, I get the following error Traceback (most recent call last):  File "C:\Python23\Lib\site-packages\pythonwin\pywin\framework\scriptutils.py", line 310, in RunScript
    exec codeObject in __main__.__dict__  File "E:\OFDMA_test\iqw.py", line 16, in ?    x[i/4]=unpack('f',a[i:i+4])[0]error: unpack str size does not match formatapparently the XP box thinks the file is alot shorter, and that can't be as it is the same file from the same media (USB stick). What is going wrong here?
/Johanimport osfrom struct import *from scipy import *f=file("c:\\tmp\\FSL_good_SNR\\Last_IQ.iqw",'r')a=f.read()f.close()x=zeros(len(a)/4)+0.0
for i in range (0, len(a),4):    x[i/4]=unpack('f',a[i:i+4])[0]y=x[0:len(x)/2-1]+1j*x[len(x)/2:len(x)-1]writer = file("c:\\tmp\\FSL_good_SNR\\IQ.csv", 'w')for item in y:    writer.write
(repr(real(item))+','+repr(imag(item))+'\n')writer.close()
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] need to get unique elements out of a 2.5Gb file

2006-02-02 Thread Rinzwind
I'd use a database if I was you.
Install for instance MYSQL or MudBase or something like that and (if
need be use Python) to insert the lines into the database. Only
storing unique lines would be failry easy.

Other sollution (with the usage of Python):
If you must use Python I'd suggest making new smaller files.
How about making files that are named with the 1st letter of each line
you find and split your file up into as many parts and your lines
start with unique characters.

You end up with lots of smaller files that just need to be merged
together (could be done with 'cat' I think?) or you could read all
those files and toss them back into 1 big file.

Something like this:

Read the 2,5G masterfile
Read lines 1 by 1
Make a new file named "1st char of line founnd".txt if it doesn't
exist and add the new line
otherwise scan this file and see if the line is not there yet and if
not there add it.

when done: merge all files.

Can't be too hard to pull off ;)
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Todays Learning Python Question From a Newbie ;)

2006-02-02 Thread Alan Gauld
Bob,

>> Write a new computer_move() function for the tic-tac-toe game to plug 
>> the hole in the computers stratergy. See if you can create an opponent 
>> that is unbeatable!
>>
>> My main problem is that I can not see how the computers stratergy can 
>> be improved as at best I can only manage a tie with the computer!

Does the computer ever go first? 
Does the computer start with a random location?
If yes to the above then the computer can be beaten since the entire 
course of a Tic-Tac-Toe game (or OXO as we call it in the UK!)
depends upon the first move location.

If no to the above then, provided the gameplay is OK, I don't know 
what the author means either.

Alan G.
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] need to get unique elements out of a 2.5Gb file

2006-02-02 Thread Alan Gauld
Hi,

<  I have a file which is 2.5 Gb.,
> 
> There are many duplicate lines.  I wanted to get rid
> of the duplicates.

First, can you use uniq which is a standard Unix/Linux OS command?

> I chose to parse to get uniqe element.
> 
> f1 = open('mfile','r')
> da = f1.read().split('\n')

This reads 2.5G of data into memory. Do you have 2.5G of 
available memory?

It then splits it into lines, so why not read the file line by line 
instead?

for da in open('myfile'):
stuff here

> dat = da[:-1]

This creates a copy of the file contents - anbother 2.5GB!
if you used da = da[:-1]  you would only have one version.

However if you read it one line at a time you can go direct 
to putting it into the Set which means you never reach 
the 2.5GB size.

> f2 = open('res','w')
> dset = Set(dat)
> for i in dset:
>f2.write(i)
>f2.write('\n')

f2.write(i+'\n')

should be slightly faster and with this size of data set that 
probably is a visible difference!

> Problem: Python says it cannot hande such a large
> file. 

Thats probably not a Python issue but an available RAM issue.
But your code doesn't need the entire file in RAM so just read 
one line at a time and avoid the list..

If its still too big you can try batching the operations. 
Only process half the lines in the file say, then merge 
the resultant reduced files. The key point is that without 
resort to much more sophisticated algorithms you must 
at some point hold the final data set in RAM, if it is too 
big the program will fail.

A final strategy is to sort the file (which can be 
done - slowly! - in batches and remove duplicate lines 
afterwards, or even as part of the sort... But if you need 
to go that far come back for more details.

HTH,

Alan G.
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Todays Learning Python Question From a Newbie ;)

2006-02-02 Thread Jon Moore
On 02/02/06, Alan Gauld <[EMAIL PROTECTED]> wrote:
Bob,>> Write a new computer_move() function for the tic-tac-toe game to plug>> the hole in the computers stratergy. See if you can create an opponent>> that is unbeatable!>>
>> My main problem is that I can not see how the computers stratergy can>> be improved as at best I can only manage a tie with the computer!Does the computer ever go first?Yes if you let it!
Does the computer start with a random location?No, if you look at the code below, it has a  predefined set of 'best moves'. 
If yes to the above then the computer can be beaten since the entirecourse of a Tic-Tac-Toe game (or OXO as we call it in the UK!)
depends upon the first move location.Thanks to  André, there is a way to win every time if you take the first move (see below), so there MUST be a whole in the computers stratergy! Based on what we all know about the game, I would say that you can not make it so that the computer can win every time, but it should be possable to make it tie.
x: 0o: 4x: 7o: 2x: 6If no to the above then, provided the gameplay is OK, I don't know
what the author means either.Alan G.The code is as follows:# set global constantsX = "X"O = "O"EMPTY = " "TIE = "TIE"
NUM_SQUARES = 9# set game instructionsdef display_instruct():    """Display game instructions."""    print \    """    Welcome to the greatest intellectual challenge of all time: Tic-Tac-Toe.  
    This will be a showdown between your human brain and my silicon processor.      You will make your move known by entering a number, 0 - 8.  The number     will correspond to the board position as illustrated:
        0 | 1 | 2    -    3 | 4 | 5    -    6 | 7 | 8    Prepare yourself, human.  The ultimate battle is about to begin. \n
    """# set questiondef ask_yes_no(question):    """Ask a yes or no question."""    response = None    while response not in ("y", "n"):
    response =  raw_input(question).lower()    return response# set ask numberdef ask_number(question, low, high):    """Ask for a number within the range"""    response = None
    while response not in range(low, high):    response =  int(raw_input(question))    return response# set piecesdef pieces():    """Determine if player or computer goes first."""
    go_first =  ask_yes_no("Do you wish to go first? (y/n): ")    if go_first == "y":    print "\nThen take the first move. You will need it ;)"    human = X    computer = O
    else:    print "\nYour bravery will be your undoingI will go first."    computer = X    human = O    return computer, human# create new boarddef new_board():
    """Create a new game board."""    board = []    for square in range(NUM_SQUARES):    board.append(EMPTY)    return board# display the boarddef display_board(board):
    """Display the board on the screen"""    print "\n\t", board[0], "|", board[1], "|", board[2]    print "\t", "-"    print "\t", board[3], "|", board[4], "|", board[5]
    print "\t", "-"    print "\t", board[6], "|", board[7], "|", board[8], "\n"# set legal movesdef legal_moves(board):    """Create list of legal moves."""
    moves = []    for square in range(NUM_SQUARES):    if board[square] == EMPTY:    moves.append(square)    return moves# set winnerdef winner(board):    """Determine the game winner"""
    WAYS_TO_WIN = ((0, 1, 2),   (3, 4, 5),   (6, 7, 8),   (0, 3, 6),   (1, 4, 7),   (2, 5, 8),   (0, 4, 8),
   (2, 4, 6))    for row in WAYS_TO_WIN:    if board[row[0]] == board[row[1]] == board[row[2]] != EMPTY:    winner = board[row[0]]    return winner    if EMPTY not in board:
    return TIE    return None# set human movedef human_move(board, human):    """Get human move."""    legal = legal_moves(board)    move = None    while move not in legal:
    move = ask_number("Where will you move? (0-8): ", 0, NUM_SQUARES)    if move not in legal:    print "\nThat square is already occupied. Please choose another.\n"    print "Fine..."
    return move# set computer movedef computer_move(board, computer, human):    """Make computer move."""    # Make a copy of the board to work with since the function will be changing the list
    board = board[:]    # The best positions to have, in order    BEST_MOVES = (4, 0, 2, 6, 8, 1, 3, 5, 7)    print "I shall take a square number",    # if computer can win, take that move
    for move in legal_moves(board):    board[move] = computer    if winner(board) ==  computer:    print move    return move    # done checking this move, undo it    board[move] = EMPTY
    #if human can win, block that move    for move in legal_moves(board):    board[move] = human    if winner(board) ==  human:    print move    retur

Re: [Tutor] Windows problem with large(?) files

2006-02-02 Thread Danny Yoo


On Thu, 2 Feb 2006, johan nilsson wrote:


> apparently the XP box thinks the file is alot shorter, and that can't be
> as it is the same file from the same media (USB stick). What is going
> wrong here?

Hi Johan,

Is it possible that you need to treat the file as a binary file?  It's
rare, but very possible that something like:

f = open(somefilename,'r')
a = f.read()

will give you different results on different platforms, because newline
translation occurs on the Windows end of things.  ("\n" --> "\r\n" or visa
versa)  So if your file coincidently has bytes with the sequential values:

##
>>> ord('\r'), ord('\n')
(13, 10)
##

then we should expect to see those two bytes collapsed down to a single
one through the mechanism of newline translation.


But if this is happening, there's an easy fix:

f = open(somefilename,'rb')
a = f.read()

where we open the file in binary mode.


Good luck!

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] printing the random seed?

2006-02-02 Thread Kent Johnson
Danny Yoo wrote:
> 
> On Thu, 2 Feb 2006, kevin parks wrote:
> 
> 
>>Danny (hope you are good!) & co,
>>
>>I see that biz about random.seed()... but in the absence of setting that
>>... does it just grab a value from the system clock?
> 
> 
> Yes.  Here's what the documentation says officially:
> 
> """current system time is also used to initialize the generator when the
> module is first imported"""

As of Python 2.4, random.seed() will attempt to use os.urandom() to 
initialize the seed; if that is not available it uses the system time.

>>Is there a way to just let it generate it's usual, known seed... but
>>then observe what that is in case you get an especially good run of
>>data?
> 
> 
> We can call seed() explicitely using system time then when we start using
> the random module, and if the results are interesting, we report that
> initial seed value too.  That way, by knowing the initial conditions, we
> can reproduce the results.

Here is the code from random.py that initializes the seed (a):
 try:
 a = long(_hexlify(_urandom(16)), 16)
 except NotImplementedError:
 import time
 a = long(time.time() * 256) # use fractional seconds

Kent

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


[Tutor] Using ioctl

2006-02-02 Thread Michael Lange
Hello,

I am writing an app that records from the soundcard using ossaudiodev.
In the OSS programmer's guide they recommend when reading data fragments from 
the soundcard
to use the fragment size as it is requested by the driver. According to the 
programmer's guide
the ioctl call to determine the requested fragment size is:

int frag_size;
if ioctl(audio_fd, SNDCTL_DSP_GETBLKSIZE, &frag_size) == -1)
error();

Unfortunately this procedure is not implemented in the ossaudiodev module, so I
tried to write it myself.
>From reading the fcntl module's docs, I came to the following solution:

try:
f = array.array('h', [0])
fcntl.ioctl(audio_fd, ossaudiodev.SNDCTL_DSP_GETBLKSIZE, f, 1)
frag_size = f.tolist()[0]
except:
frag_size = -1
if frag_size <= 0:
frag_size = 4096


This *seems* to work, I tried several soundcards and got frag_size values like 
4096, 8192 or 16384 .
However I am not really sure about what I am doing there, so I would feel more 
confident
if anyone could explain how ioctl is supposed to be used ( I also felt that I 
should use
the try...except block for the call in case it fails, but I don't have an idea 
"except *what*").

Any hints are much appreciated.

thanks in advance

Michael
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Windows problem with large(?) files

2006-02-02 Thread johan nilsson
Thanks Danny!that solved it.JohanOn 2/2/06, Danny Yoo <[EMAIL PROTECTED]> wrote:
On Thu, 2 Feb 2006, johan nilsson wrote:> apparently the XP box thinks the file is alot shorter, and that can't be
> as it is the same file from the same media (USB stick). What is going> wrong here?Hi Johan,Is it possible that you need to treat the file as a binary file?  It'srare, but very possible that something like:
f = open(somefilename,'r')a = f.read()will give you different results on different platforms, because newlinetranslation occurs on the Windows end of things.  ("\n" --> "\r\n" or visa
versa)  So if your file coincidently has bytes with the sequential values:##>>> ord('\r'), ord('\n')(13, 10)##then we should expect to see those two bytes collapsed down to a single
one through the mechanism of newline translation.But if this is happening, there's an easy fix:f = open(somefilename,'rb')a = f.read()where we open the file in binary mode.
Good luck!
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Todays Learning Python Question From a Newbie ;)

2006-02-02 Thread Wolfram Kraus
Jon Moore wrote:
[...]

> Thanks to  André, there is a way to win every time if you take the first 
> move (see below), so there MUST be a whole in the computers stratergy! 
> Based on what we all know about the game, I would say that you can not 
> make it so that the computer can win every time, but it should be 
> possable to make it tie.
> 
> x: 0
> o: 4
> x: 7
> o: 2
  ^
Make this 6,3,8 or 5 and it will be a tie

> x: 6
> 
> 0 | 1 | 2
> -
> 3 | 4 | 5
> -
> 6 | 7 | 8
> 
>


Wolfram

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


[Tutor] Trapping a Dr Watson error

2006-02-02 Thread Ben Vinger
Hello

I have a script based on:
http://aspn.activestate.com/ASPN/docs/ActivePython/2.4/pywin32/Windows_NT_Eventlog.html
It collects eventlogs data from many Windows servers.
I know how to handle normal Python Tracebacks, but my
script bombs out with a Dr Watson error when
connecting to one particular server.
(It even runs fine against the Application log of this
server, but bombs out on the System log).  Anyways, I
want to know if it is possible to trap, handle and
survive a Dr Watson error programatically

Thanks
Ben




___ 
To help you stay safe and secure online, we've developed the all new Yahoo! 
Security Centre. http://uk.security.yahoo.com
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Todays Learning Python Question From a Newbie ;)

2006-02-02 Thread Jon Moore
All that does is reverse the hole!?!?x:2o:4x:7o:0x:80:5    O |   | X    -      | O | O    -      | X | X On 02/02/06, 
Wolfram Kraus <[EMAIL PROTECTED]> wrote:
Jon Moore wrote:[...]> Thanks to  André, there is a way to win every time if you take the first> move (see below), so there MUST be a whole in the computers stratergy!> Based on what we all know about the game, I would say that you can not
> make it so that the computer can win every time, but it should be> possable to make it tie.>> x: 0> o: 4> x: 7> o: 2  ^Make this 6,3,8 or 5 and it will be a tie
> x: 6>> 0 | 1 | 2> -> 3 | 4 | 5> -> 6 | 7 | 8>
>Wolfram___Tutor maillist  -  Tutor@python.orghttp://mail.python.org/mailman/listinfo/tutor
-- Best RegardsJon Moore
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Todays Learning Python Question From a Newbie ;)

2006-02-02 Thread Andre Roberge
As I indicated in private email yesterday to Jon, there is indeed a
hole in the computer stratey when the following three first moves are
made:
x:2
o:4  (first available "best move" for the computer)
x:7

I also sketched a "solution", which I will rephrase here in a different way.

The next "best move" from the list leads to a win for the human, if
she/he plays correctly.
So, one has to put in "somewhere" (there are a few possible places) a
test to see if this combination of the first three moves has occurred;
if so, hard-code a computer response that defeats this strategy; if
not, go and use the standard "best move" list.

André

On 2/2/06, Jon Moore <[EMAIL PROTECTED]> wrote:
> All that does is reverse the hole!?!?
>
> x:2
> o:4
> x:7
> o:0
> x:8
> 0:5
>
> O |   | X
> -
>   | O | O
> -
>   | X | X
>
>
> On 02/02/06, Wolfram Kraus <[EMAIL PROTECTED]> wrote:
> > Jon Moore wrote:
> > [...]
> >
> > > Thanks to  André, there is a way to win every time if you take the first
> > > move (see below), so there MUST be a whole in the computers stratergy!
> > > Based on what we all know about the game, I would say that you can not
> > > make it so that the computer can win every time, but it should be
> > > possable to make it tie.
> > >
> > > x: 0
> > > o: 4
> > > x: 7
> > > o: 2
> >   ^
> > Make this 6,3,8 or 5 and it will be a tie
> >
> > > x: 6
> > >
> > > 0 | 1 | 2
> > > -
> > > 3 | 4 | 5
> > > -
> > > 6 | 7 | 8
> > >
> > >
> >
> >
> > Wolfram
> >
> > ___
> > Tutor maillist  -  Tutor@python.org
> > http://mail.python.org/mailman/listinfo/tutor
> >
>
>
>
> --
> Best Regards
>
> Jon Moore
> ___
> Tutor maillist  -  Tutor@python.org
> http://mail.python.org/mailman/listinfo/tutor
>
>
>
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


[Tutor] list method help

2006-02-02 Thread Michael Haft


Hello,
  was just trying to do something and tried the following code:

list = ["1", "test", "1.5"]

for x in list:
 print list.pop(x)

I get the following error:

print list.pop(x)
TypeError: an integer is required

Does this mean i can't use a for loop to pop things from a list? or is 
there another way to do it?

I also tried the following:

list = ["1", "test", "1.5"]

for x in list:
 print list.pop(0)

which worked but returned the following:

1
test

Why did it not return the last value in the list?

Thanks

Mike


Michael Haft
School of Biological Sciences
Plant & Soil Science
Cruickshank Building
St.Machar Drive
Aberdeen AB24 3UU
E-mail: [EMAIL PROTECTED]

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


[Tutor] critique my wrapper

2006-02-02 Thread Christopher Spears
This is a class I created that wraps a list.  Could
someone please critique the class?

class MyList:
def __init__(self, aList=None):
if aList is None:
self.mylist = []
else:
self.mylist = aList[:]
def __getitem__(self, index):
return self.mylist[index]
def __setitem__(self, index, value):
self.mylist[index] = value
def __len__(self):
return len(self.mylist)
def __delitem__(self, index):
del self.mylist[index]
def __add__(self, other):
self.mylist = self.mylist + other
def __repr__(self):
return '%s' % self.mylist
def append(self, other):
self.mylist.append(other)
def count(self, value):
return self.mylist.count(value)
def index(self, value):
return self.mylist.index(value)
def extend(self, seq):
self.mylist.extend(seq)
def insert(self, index, value):
self.mylist.insert(index, value)
def pop(self, index):
return self.mylist.pop(index)
def remove(self, value):
self.mylist.remove(value)
def reverse(self):
self.mylist.reverse()
def sort(self):
self.mylist.sort()




___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] list method help

2006-02-02 Thread Alan Gauld
> list = ["1", "test", "1.5"]
> for x in list:
> print list.pop(x)
> 
> I get the following error:
> 
> print list.pop(x)
> TypeError: an integer is required
> 
> Does this mean i can't use a for loop to pop things from a list? 

No it means pop takes an optional *index* as an argument.

> list = ["1", "test", "1.5"]
> for x in list:
> print list.pop(0)
> 
> which worked but returned the following:
> 
> 1
> test
> 
> Why did it not return the last value in the list?

Because you provided an index of 0 which is the beginning.
Try

 list = ["1", "test", "1.5"]
 for x in list:
 print list.pop()

Or maybe more usefully:

for x in range(len(list)):
print list.pop()

BTW list is a bad name for a variable since it masks the 
builtin list() function.

HTH,

Alan G
Author of the learn to program web tutor
http://www.freenetpages.co.uk/hp/alan.gauld


___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] critique my wrapper

2006-02-02 Thread Andre Roberge
On 2/2/06, Christopher Spears <[EMAIL PROTECTED]> wrote:
> This is a class I created that wraps a list.  Could
> someone please critique the class?
>
> class MyList:
> def __init__(self, aList=None):
> if aList is None:
> self.mylist = []
> else:
> self.mylist = aList[:]
> def __getitem__(self, index):
> return self.mylist[index]
> def __setitem__(self, index, value):
> self.mylist[index] = value
> def __len__(self):
> return len(self.mylist)
> def __delitem__(self, index):
> del self.mylist[index]
> def __add__(self, other):
> self.mylist = self.mylist + other
> def __repr__(self):
> return '%s' % self.mylist
> def append(self, other):
[snip]

It's hard to critique without knowing your intentions.  Here's a
simpler class that should
do the same as yours!

class MyList2(list):
def __init__(self, aList=[]):
 list(aList)

I may have missed something but, unless you are re-defining a list
method, it is easier to simply subclass list like I have done - and
only re-define the methods whose behaviour you want to redefine, or
add new method.  Otherwise, simply use

a_list = list()  !!!

Then again, perhaps I am missing something obvious...

André
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] list method help

2006-02-02 Thread Danny Yoo


On Thu, 2 Feb 2006, Michael Haft wrote:

>   was just trying to do something and tried the following code:
>
> list = ["1", "test", "1.5"]
>
> for x in list:
>  print list.pop(x)
>
> I get the following error:
>
> print list.pop(x)
> TypeError: an integer is required


Hi Michael,

The error message is accurate: list.pop() is only supposed to take an
integer.

If we take a look at the documentation of list.pop(), we should be able to
see why:

http://www.python.org/doc/lib/typesseq-mutable.html

The problem is one of us being confusing about the domain that pop() takes
in.  pop() is supposed to take in the position of the element we're trying
to pop, not the element itself.  Does this make sense?




> Does this mean i can't use a for loop to pop things from a list? or is
> there another way to do it?
>
> I also tried the following:
>
> list = ["1", "test", "1.5"]
>
> for x in list:
>  print list.pop(0)
>
> which worked but returned the following:
>
> 1
> test
>
> Why did it not return the last value in the list?

Simultaneous for-loop iteration and removal from a list is fraught with
subtle issues.  What's going on is that the for-loop expects all the
elements to stay in place.  In the example above, imagine an arrow aimed
at a particular element of a list:

["1", "test", "1.5"]
  ^

During iteration, the arrow moves across the list till it hits the end of
the list.  Note, though, that list.pop(0) pulls elements toward the left:

["test", "1.5"]
   ^

and if the arrow naively marches forward, as in regular list iteration:

["test", "1.5"]
   ^

and we pop(0) again, then we again push the remaining element forward:

["1.5"]
  ^

but our arrow's out of the list's range!  So we're done iterating across
the list's structure, and this "premature" exit is what you're seeing.


It's this interplay between the shifting behavior of pop(0) with the
obliviousness of the iterator that causes these subtle issues.  This is
not really a Python-specific issue, but a fundamental one involving
mutation across a list.  (For example, Java has the same issues, and
that's why Java's Iterator has a remove() method to attack this specific
issue.)

One way to get around this is to not use an iterator, but to use a
different condition that's more stable under shifting, like checking for
list length:

while len(mylist) != 0:
   ...

or we can pop() starting backwards, from the end of the list, which can
less disruptive to the list's structure than pop()ping from the front.


Just out of curiosity, though, what are you trying to do?  Why pop()
altogether?  It might be that you can solve whatever problem you're doing
with very little list mutation.  Tell us more about what you're trying to
do, and we can give more help.

Good luck!

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] list method help

2006-02-02 Thread Chris or Leslie Smith

| Hello,
|  was just trying to do something and tried the following code:
| 
| list = ["1", "test", "1.5"]
| 
| for x in list:
| print list.pop(x)
| 
| I get the following error:
| 
| print list.pop(x)
| TypeError: an integer is required
| 
| Does this mean i can't use a for loop to pop things from a list? or is
| there another way to do it?

In the interactive window you can request help to see if that gives you a clue 
as to what might be going wrong:

###
>>> help(list.pop)
Help on method_descriptor:

pop(...)
L.pop([index]) -> item -- remove and return item at index (default last)

###

So you must supply an index (which is an integer) defining which item you want 
to remove (or else supply no argument and automatically get the default which 
is the last item). You should not tell pop *what* you want to pop--which is 
what you did with the "x"--you should tell it which item *number* you want to 
pop--which you did in your next attempt.

| 
| I also tried the following:
| 
| list = ["1", "test", "1.5"]
| 
| for x in list:
| print list.pop(0)
| 
| which worked but returned the following:
| 
| 1
| test
| 
| Why did it not return the last value in the list?
| 

The "for x in list" is shorthand for the following equivalent syntax:

i=0
while i  range(3) => [0, 1, 2]

Another approach you could use is to keep popping off elements until the list 
is consummed:

while list:
print list.pop(0)

-
OK, here's the aside--you might want to skip this for now.
-

If we reshuffle the list while we are walking through it, we can keep printing 
the same thing (not that we would really want to, but you get the idea that 
some internal index is advancing you through the list)
###
>>> for x in l:
...  print x,l
...  l[:]=l[-1:]+l[0:-1] #rotate the list to the right
...  
1 ['1', 'test', '1.5']
1 ['1.5', '1', 'test']
1 ['test', '1.5', '1']
###

But here is the first attempt that I made to do this and it gave a different 
result:
###
>>> for x in l:
...  print x,l
...  l=l[-1:]+l[0:-1]
...  
1 ['1', 'test', '1.5']
test ['1.5', '1', 'test']
1.5 ['test', '1.5', '1']
###

So it appears that not only does the "for x in l" keep track of an index, it 
also keeps track of the original 'l' and allows me to point an 'l' in the loop 
to something separate from the one it is keeping track of. So it seems the "for 
x in l" is doing something like:

i=0
tempList = list
while i>> l=range(3)
>>> a=l # 'a' is pointing at what 'l' is pointing at
>>> l[0]=42 # I make a change to the thing that 'l' points to
>>> print a
[42, 1, 2]
>>> print l
[42, 1, 2]
>>> 
###

Since a and l point at the same thing, they both show the change. But compare 
that to this:

###
>>> l=range(3)
>>> a=l  # 'a' and 'l' point to the same thing
>>> l=42 # here I make 'l' point to something else
>>> print a
[0, 1, 2]
>>> print l
42
###

This perplexing issue is something that bites most of us at some time. I hope I 
haven't made it more perplexing ;-) If you have more questions, ask. 

/c
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor