[back to Python notes I]

The questions I had after one day of using python

Thanks to Carl for answers!

How to find the first item in a list for which a function is true?
This is from http://naeblis.cx/rtomayko/2004/09/13/cleanest-python-find-in-list-function

def find(f, seq):
    """Return first item in sequence where f(item) == True."""
    for item in seq:
        if f(item): 
            return item

## eg to find in the list 'codewords' the first element whose attribute 'index' is equal to s,
co = find(lambda p: p.index == s, codewords)

There is a useful list method called index. The argument of index is the VALUE of the obect. Great for finding the index of the integer "4" in list c=[6,4,7,9], for example. (c.index(4)). But how can I get the same behaviour for more complex classes of object? I'm imagining that I could declare a special method of an object, say "__value__", which is consulted by the list method called index.
ANSWER: overload the __eq__ method of the class. Declare the value of an item to be equal to the value of that attribute, then use the ".index(value)" function. Here is a code fragment illustrating this method:

class node:
    def __eq__(self,other): ## for use by index()
        return (self.value == other)
 ...

## later...
        foundit = c.index(second) 
## returns the index in the list c at which the node with value "second" is located


How to find the first item in a list for which a particular attribute has a given value?
Answer: Use one of the two methods described above using find and index.

When I a make an object CLASS there are methods I want individual OBJECTS in that CLASS to have and there are also other methods that should belong to LISTS (or other sets) of those objects.
For example, a list of "number"s has a property called the sum. When I define a "number" CLASS, how do I define the method "sum" associated with a LIST of numbers?
Apparently the standard way to do this is simply to write a package in which the class is defined, and, in close proximity, include the definition of the function that acts on a list. By convention, you do not do type checking (for example, checking that the LIST that is delivered to the SUM command is of the correct class). This is not especially necessary, because a beautiful object-oriented program doesn't need type checking.

When I map a function on a list, do I have access to the value of the iterator?

Here is the question in more detail.
I'd like to have a function to get from

   counts = [ 10, 5, 2, 3 ]
to
   c = [ node( 10 , 1 ) , node( 5 , 2 ) , node( 2 , 3 ) , node( 3 , 4 ) ] 
in a more elegant way than

	c=[]
	m=0
	for co in counts :
	    m += 1
	    c.append( node( co, m ) )
Can map do this?

Answer: Yes. You can give map extra arguments. Here is an example that illustrates the method.

def node(a,b) : return ("answer returned by",a,b)  ; pass
counts=[10,5,2,3]
map( node, counts, range(0,len(counts) ) )

What is the elegant way to make a package that you can execute directly (using python filename.py), and that provides some functions to be imported to other python? I want to be able to easily test my package while developing it.
Solution: put all the stuff you want executed inside a function like this
def test():
	## functions that you want to execute when testing here
and then at the end of the file, have this line:
if __name__ == '__main__': test()
Then you can execute the file directly and you can also use
from filename import *
without that stuff executing.

Explanation: Modules are objects, and all modules have a built-in attribute __name__. A module's __name__ depends on how you're using the module. If you import the module, then __name__ is the module's filename, without directory path or file extension. But you can also run the module directly as a standalone program, in which case __name__ will be a special default value, __main__.

OK. But what if I want the package to be executable from within emacs using C-c C-c, and I want it to be executable from a shell using python file.py < source > sink and I want the two behaviours to be different in these cases? -- eg, "test" in the first case, and "real_thing" in the second? A similar issue is: if I am developing in emacs, but want the python program to be interactive, using raw_input() for example, can I still use C-c C-c? - How do I get the raw input it?
Solution:

if __name__ == '__main__':
    import sys
    #    find out the command
    #    print "Test has been called with the following argv:"
    #    print sys.argv
    if sys.argv == [''] : ## probably we have been invoked by C-c C-c
        test()
        pass
    else : ## read data from stdin and write to stdout
        run() 
        pass

If I have edited a package, how do I force an interactive python session to re-read that package? It seems that
from filename import *
does not work!

 reload(modulename)

How to read a load of stuff from a file?
I learned this from http://www.oreilly.com/catalog/lpython/chapter/ch09.html. Here is the equivalent of the perl command

 while ( $line = <STDIN> ) {
 }
Python equivalent, reading one line at a time:

    for line in sys.stdin.readlines():

How to quickly execute a piece of python from inside emacs?
C-c C-c

How do I get emacs to be in python mode for all files of form blah.py?


When I do a sort, how can I preserve the PERMUTATION of indices that the sort induces?

Answer:

a=[15,13,17,11]
c=list( [ a[i],i ] for i in range (len(a)) )
c.sort()
c
-> [[11, 3], [13, 1], [15, 0], [17, 2]]
Note that by default, sort will, if confronted by the task of comparing two sets, use the first element in the set.

For a good introduction to sort, see http://www.amk.ca/python/howto/sorting/sorting.html.


What are some non-obvious pieces of syntax?
  1. As the previous answer illustrates, you are allowed to put for in unexpected places:
    sum( i for i in range(10) )
  • JOINING: To join a list of strings together into a single string, you can use the SEPARATOR as the actor:
    
    ## string.join(list) means 'join the list using "string" as separator'
    ## example:
        outputfile.write( ''.join( ['a','b'] ) ) 
    

  • How to use split to split a string into its component characters?
    Answer: To split at ":", s.split(":") - I haven't managed to do this with split (I thought that the separator should be '', but it didn't work), but you can use
    for c in stringname
    to access the characters in a string.

    How to do regexp replacements?
    You build the regexp first then use it. And you can't use it in place without mentioning the string name twice. Not as nice as perl! Note the use of the RAW string indicator, "r".
    import re
    mm = re.compile(r"\b(red|green)\b(?=.*salad)", re.IGNORECASE | re.DOTALL ) 
    # DOTALL means match newlines
    str = "Red salad is bred for greenery and green thoughts about salad and red men"
    corrected_str = mm.sub(r'COLOR', str)
    print corrected_str
    
    More about regex's. I used regex's and matches in this simple perl-like data-file processor.

    I can't get print to print what I want! It keeps adding spaces and so forth.
    If you want to print a string without any trailing characters at all, your best bet is to use sys.stdout.write()
    import sys
    for i in range(10): sys.stdout.write("*")
    sys.stdout.write("\n")