diff --git a/comprehensions.html b/comprehensions.html index fa30792..6d19fbe 100644 --- a/comprehensions.html +++ b/comprehensions.html @@ -50,146 +50,100 @@ body{counter-reset:h1 3}
>>> import os ① >>> print(os.getcwd()) ② -C:\Python31 +C:\Python31 >>> os.chdir('/Users/pilgrim/diveintopython3/examples') ③ >>> print(os.getcwd()) ④ -C:\Users\pilgrim\diveintopython3\examples+C:\Users\pilgrim\diveintopython3\examples
c:\Python31. If you run the Python Shell from the command line, the current working directory starts as the directory you were in when you ran python3.
-os module comes with Python; you can import it anytime, anywhere.
+os.getcwd() function to get the current working directory. When you run the graphical Python Shell, the current working directory starts as the directory where the Python Shell executable is. On Windows, this depends on where you installed Python; the default directory is c:\Python31. If you run the Python Shell from the command line, the current working directory starts as the directory you were in when you ran python3.
+os.chdir() function to change the current working directory.
+os.chdir() function, I used a Linux-style pathname (forward slashes, no drive letter) even though I’m on Windows. This is one of the places where Python tries to paper over the differences between operating systems.
os.path moduleFIXME The os.path module has several functions for manipulating files and directories. Here, we're looking at handling pathnames and listing the contents of a directory.
+
While we’re on the subject of directories, I want to point out the os.path submodule. os.path contains functions for manipulating filenames and directory names.
+
->>> import os
->>> os.path.join("c:\\music\\ap\\", "mahadeva.mp3") ① ②
-'c:\\music\\ap\\mahadeva.mp3'
->>> os.path.join("c:\\music\\ap", "mahadeva.mp3") ③
-'c:\\music\\ap\\mahadeva.mp3'
->>> os.path.expanduser("~") ④
-'c:\\Documents and Settings\\mpilgrim\\My Documents'
->>> os.path.join(os.path.expanduser("~"), "Python") ⑤
-'c:\\Documents and Settings\\mpilgrim\\My Documents\\Python'
+>>> import os
+>>> print(os.path.join('/Users/pilgrim/diveintopython3/examples/', 'humansize.py')) ①
+/Users/pilgrim/diveintopython3/examples/humansize.py
+>>> print(os.path.join('/Users/pilgrim/diveintopython3/examples', 'humansize.py')) ②
+/Users/pilgrim/diveintopython3/examples\humansize.py
+>>> print(os.path.expanduser('~')) ③
+c:\Users\pilgrim
+>>> print(os.path.join(os.path.expanduser('~'), 'diveintopython3', 'examples', 'humansize.py')) ④
+c:\Users\pilgrim\diveintopython3\examples\humansize.py
os.path is a reference to a module -- which module depends on your platform. Just as getpass encapsulates differences between platforms by setting getpass to a platform-specific function, os encapsulates differences between platforms by setting path to a platform-specific module.
-join function of os.path constructs a pathname out of one or more partial pathnames. In this case, it simply concatenates strings. (Note that dealing
- with pathnames on Windows is annoying because the backslash character must be escaped.)
-join will add an extra backslash to the pathname before joining it to the filename. I was overjoyed when I discovered this, since
-addSlashIfNecessary is one of the stupid little functions I always need to write when building up my toolbox in a new language. Do not write this stupid little function in Python; smart people have already taken care of it for you.
-expanduser will expand a pathname that uses ~ to represent the current user's home directory. This works on any platform where users have a home directory, like Windows,
-UNIX, and Mac OS X; it has no effect on Mac OS.
-os.path.join() function constructs a pathname out of one or more partial pathnames. In this case, it simply concatenates strings.
+join will add an extra backslash to the pathname before joining it to the filename. I was overjoyed when I discovered this, since addSlashIfNecessary() is one of the stupid little functions I always need to write when building up my toolbox in a new language. Do not write this stupid little function in Python; smart people have already taken care of it for you.
+os.path.expanduser() function will expand a pathname that uses ~ to represent the current user’s home directory. This works on any platform where users have a home directory, including Linux, Mac OS X, and Windows.
+FIXME +
os.path also contains functions to split full pathnames, directory names, and filenames into their constituent parts.
-
>>> os.path.split("c:\\music\\ap\\mahadeva.mp3") ①
-('c:\\music\\ap', 'mahadeva.mp3')
->>> (filepath, filename) = os.path.split("c:\\music\\ap\\mahadeva.mp3") ②
->>> filepath ③
-'c:\\music\\ap'
->>> filename ④
-'mahadeva.mp3'
->>> (shortname, extension) = os.path.splitext(filename) ⑤
->>> shortname
-'mahadeva'
->>> extension
-'.mp3'
++>>> pathname = '/Users/pilgrim/diveintopython3/examples/humansize.py' +>>> os.path.split(pathname) ① +('/Users/pilgrim/diveintopython3/examples', 'humansize.py') +>>> (dirname, filename) = os.path.split(pathname) ② +>>> dirname ③ +'/Users/pilgrim/diveintopython3/examples' +>>> filename ④ +'humansize.py' +>>> (shortname, extension) = os.path.splitext(filename) ⑤ +>>> shortname +'humansize' +>>> extension +'.py'
split function splits a full pathname and returns a tuple containing the path and filename. Remember when I said you could use
-multi-variable assignment to return multiple values from a function? Well, split is such a function.
+split function splits a full pathname and returns a tuple containing the path and filename. Remember when I said you could use multi-variable assignment to return multiple values from a function? The os.path.split() function does exactly that.
split function into a tuple of two variables. Each variable receives the value of the corresponding element of the returned tuple.
-split, the file path.
-split, the filename.
-os.path also contains a function splitext, which splits a filename and returns a tuple containing the filename and the file extension. You use the same technique
- to assign each of them to separate variables.
-FIXME - -
>>> os.listdir("c:\\music\\_singles\\") ①
-['a_time_long_forgotten_con.mp3', 'hellraiser.mp3',
-'kairo.mp3', 'long_way_home1.mp3', 'sidewinder.mp3',
-'spinning.mp3']
->>> dirname = "c:\\"
->>> os.listdir(dirname) ②
-['AUTOEXEC.BAT', 'boot.ini', 'CONFIG.SYS', 'cygwin',
-'docbook', 'Documents and Settings', 'Incoming', 'Inetpub', 'IO.SYS',
-'MSDOS.SYS', 'Music', 'NTDETECT.COM', 'ntldr', 'pagefile.sys',
-'Program Files', 'Python20', 'RECYCLER',
-'System Volume Information', 'TEMP', 'WINNT']
->>> [f for f in os.listdir(dirname)
-... if os.path.isfile(os.path.join(dirname, f))] ③
-['AUTOEXEC.BAT', 'boot.ini', 'CONFIG.SYS', 'IO.SYS', 'MSDOS.SYS',
-'NTDETECT.COM', 'ntldr', 'pagefile.sys']
->>> [f for f in os.listdir(dirname)
-... if os.path.isdir(os.path.join(dirname, f))] ④
-['cygwin', 'docbook', 'Documents and Settings', 'Incoming',
-'Inetpub', 'Music', 'Program Files', 'Python20', 'RECYCLER',
-'System Volume Information', 'TEMP', 'WINNT']
-listdir function takes a pathname and returns a list of the contents of the directory.
-listdir returns both files and folders, with no indication of which is which.
-isfile function of the os.path module to separate the files from the folders. isfile takes a pathname and returns 1 if the path represents a file, and 0 otherwise. Here you're using os.path.join to ensure a full pathname, but isfile also works with a partial path, relative to the current working directory. You can use os.getcwd() to get the current working directory.
-os.path also has a isdir function which returns 1 if the path represents a directory, and 0 otherwise. You can use this to get a list of the subdirectories
- within a directory.
+os.path.split() function, the file path.
+os.path.split() function, the filename.
+os.path also contains the os.path.splitext() function, which splits a filename and returns a tuple containing the filename and the file extension. You use the same technique to assign each of them to separate variables.
glob moduleFIXME - -
def listDirectory(directory, fileExtList):
- "get list of file info objects for files of particular extensions"
- fileList = [os.path.normcase(f)
- for f in os.listdir(directory)] ① ②
- fileList = [os.path.join(directory, f)
- for f in fileList
- if os.path.splitext(f)[1] in fileExtList] ③ ④ ⑤
-os.listdir(directory) returns a list of all the files and folders in directory.
-os.path.normcase(f) to normalize the case according to operating system defaults. normcase is a useful little function that compensates for case-insensitive operating systems that think that mahadeva.mp3 and mahadeva.MP3 are the same file. For instance, on Windows and Mac OS, normcase will convert the entire filename to lowercase; on UNIX-compatible systems, it will return the filename unchanged.
-os.path.splitext(f) to split each filename into name and extension.
-listDirectory function).
-os.path.join(directory, f) to construct the full pathname of the file, and return a list of the full pathnames.
--- -☞Whenever possible, you should use the functions in
osandos.pathfor file, directory, and path manipulations. These modules are wrappers for platform-specific modules, so functions likeos.path.split()work on UNIX, Windows, Mac OS X, and any other platform supported by Python. -
There is one other way to get the contents of a directory. It's very powerful, and it uses the sort of wildcards that you may already be familiar with from working on the command line. +
The glob module is another tool in the Python standard library. It’s an easy way to get the contents of a directory programmatically, and it uses the sort of wildcards that you may already be familiar with from working on the command line.
->>> os.listdir("c:\\music\\_singles\\") ①
-['a_time_long_forgotten_con.mp3', 'hellraiser.mp3',
-'kairo.mp3', 'long_way_home1.mp3', 'sidewinder.mp3',
-'spinning.mp3']
->>> import glob
->>> glob.glob('c:\\music\\_singles\\*.mp3') ②
-['c:\\music\\_singles\\a_time_long_forgotten_con.mp3',
-'c:\\music\\_singles\\hellraiser.mp3',
-'c:\\music\\_singles\\kairo.mp3',
-'c:\\music\\_singles\\long_way_home1.mp3',
-'c:\\music\\_singles\\sidewinder.mp3',
-'c:\\music\\_singles\\spinning.mp3']
->>> glob.glob('c:\\music\\_singles\\s*.mp3') ③
-['c:\\music\\_singles\\sidewinder.mp3',
-'c:\\music\\_singles\\spinning.mp3']
->>> glob.glob('c:\\music\\*\\*.mp3')④
-
+>>> os.chdir('/Users/pilgrim/diveintopython3/')
+>>> import glob
+>>> glob.glob('examples/*.xml') ①
+['examples\\feed-broken.xml',
+ 'examples\\feed-ns0.xml',
+ 'examples\\feed.xml']
+>>> os.chdir('examples/') ②
+>>> glob.glob('*test*.py') ③
+['alphameticstest.py',
+ 'pluraltest1.py',
+ 'pluraltest2.py',
+ 'pluraltest3.py',
+ 'pluraltest4.py',
+ 'pluraltest5.py',
+ 'pluraltest6.py',
+ 'romantest1.py',
+ 'romantest10.py',
+ 'romantest2.py',
+ 'romantest3.py',
+ 'romantest4.py',
+ 'romantest5.py',
+ 'romantest6.py',
+ 'romantest7.py',
+ 'romantest8.py',
+ 'romantest9.py']
os.listdir simply takes a directory path and lists all files and directories in that directory.
-glob module, on the other hand, takes a wildcard and returns the full path of all files and directories matching the wildcard.
- Here the wildcard is a directory path plus "*.mp3", which will match all .mp3 files. Note that each element of the returned list already includes the full path of the file.
-music directory, with several subdirectories within it, with .mp3 files within each subdirectory. You can get a list of all of those with a single call to glob, by using two wildcards at once. One wildcard is the "*.mp3" (to match .mp3 files), and one wildcard is within the directory path itself, to match any subdirectory within c:\music. That's a crazy amount of power packed into one deceptively simple-looking function!
+glob module takes a wildcard and returns the path of all files and directories matching the wildcard. In this example, the wildcard is a directory path plus “*.xml”, which will match all .xml files in the examples subdirectory.
+examples subdirectory. The os.chdir() function can take relative pathnames.
+.py extension and contain the word test anywhere in their filename.
Now you’re ready to learn about comprehensions. +
One of the most powerful features of Python is the list comprehension, which provides a compact way of mapping a list into another list by applying a function to each
@@ -250,6 +204,51 @@ as params., but each element in the
like the output of the program. All that remains is to join the elements in this list into a single string.
+items()
FIXME + +
+>>> print("\n".join(["{0:>8} {1}".format(humansize.approximate_size(os.stat(f).st_size, False), os.path.abspath(f)) for f in glob.glob('*.py')]))
+ 2.5 KB c:\Users\pilgrim\diveintopython3\examples\alphametics.py
+ 2.5 KB c:\Users\pilgrim\diveintopython3\examples\alphameticstest.py
+ 1.5 KB c:\Users\pilgrim\diveintopython3\examples\fibonacci.py
+ 1.8 KB c:\Users\pilgrim\diveintopython3\examples\fibonacci2.py
+ 2.5 KB c:\Users\pilgrim\diveintopython3\examples\humansize.py
+ 0.2 KB c:\Users\pilgrim\diveintopython3\examples\oneline.py
+ 1.9 KB c:\Users\pilgrim\diveintopython3\examples\plural1.py
+ 2.3 KB c:\Users\pilgrim\diveintopython3\examples\plural2.py
+ 2.3 KB c:\Users\pilgrim\diveintopython3\examples\plural3.py
+ 2.3 KB c:\Users\pilgrim\diveintopython3\examples\plural4.py
+ 2.4 KB c:\Users\pilgrim\diveintopython3\examples\plural5.py
+ 2.8 KB c:\Users\pilgrim\diveintopython3\examples\plural6.py
+ 3.0 KB c:\Users\pilgrim\diveintopython3\examples\pluraltest1.py
+ 3.0 KB c:\Users\pilgrim\diveintopython3\examples\pluraltest2.py
+ 3.0 KB c:\Users\pilgrim\diveintopython3\examples\pluraltest3.py
+ 3.0 KB c:\Users\pilgrim\diveintopython3\examples\pluraltest4.py
+ 3.0 KB c:\Users\pilgrim\diveintopython3\examples\pluraltest5.py
+ 6.1 KB c:\Users\pilgrim\diveintopython3\examples\pluraltest6.py
+ 0.5 KB c:\Users\pilgrim\diveintopython3\examples\regression.py
+ 2.2 KB c:\Users\pilgrim\diveintopython3\examples\roman1.py
+ 3.4 KB c:\Users\pilgrim\diveintopython3\examples\roman10.py
+ 2.3 KB c:\Users\pilgrim\diveintopython3\examples\roman2.py
+ 2.3 KB c:\Users\pilgrim\diveintopython3\examples\roman3.py
+ 2.5 KB c:\Users\pilgrim\diveintopython3\examples\roman4.py
+ 2.7 KB c:\Users\pilgrim\diveintopython3\examples\roman5.py
+ 3.6 KB c:\Users\pilgrim\diveintopython3\examples\roman6.py
+ 3.7 KB c:\Users\pilgrim\diveintopython3\examples\roman7.py
+ 3.7 KB c:\Users\pilgrim\diveintopython3\examples\roman8.py
+ 3.7 KB c:\Users\pilgrim\diveintopython3\examples\roman9.py
+ 4.0 KB c:\Users\pilgrim\diveintopython3\examples\romantest1.py
+ 6.7 KB c:\Users\pilgrim\diveintopython3\examples\romantest10.py
+ 4.2 KB c:\Users\pilgrim\diveintopython3\examples\romantest2.py
+ 4.5 KB c:\Users\pilgrim\diveintopython3\examples\romantest3.py
+ 4.7 KB c:\Users\pilgrim\diveintopython3\examples\romantest4.py
+ 5.3 KB c:\Users\pilgrim\diveintopython3\examples\romantest5.py
+ 6.1 KB c:\Users\pilgrim\diveintopython3\examples\romantest6.py
+ 6.3 KB c:\Users\pilgrim\diveintopython3\examples\romantest7.py
+ 6.5 KB c:\Users\pilgrim\diveintopython3\examples\romantest8.py
+ 6.6 KB c:\Users\pilgrim\diveintopython3\examples\romantest9.py
+ 0.4 KB c:\Users\pilgrim\diveintopython3\examples\stdout.py
+
⁂