100% found this document useful (11 votes)
78 views71 pages

Data Structures and Algorithms in Python 1st Edition by Michael Goodrich, Roberto Tamassia, Michael Goldwasser ISBN 9781118476734 1118476735

The document promotes the book 'Data Structures and Algorithms in Python' by Goodrich, Tamassia, and Goldwasser, which serves as an introduction to data structures and algorithms for beginners. It emphasizes an object-oriented approach and provides numerous examples and online resources to enhance learning. Additionally, it outlines the book's structure, prerequisites, and its relevance to computer science curricula.

Uploaded by

yoneyjitca
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (11 votes)
78 views71 pages

Data Structures and Algorithms in Python 1st Edition by Michael Goodrich, Roberto Tamassia, Michael Goldwasser ISBN 9781118476734 1118476735

The document promotes the book 'Data Structures and Algorithms in Python' by Goodrich, Tamassia, and Goldwasser, which serves as an introduction to data structures and algorithms for beginners. It emphasizes an object-oriented approach and provides numerous examples and online resources to enhance learning. Additionally, it outlines the book's structure, prerequisites, and its relevance to computer science curricula.

Uploaded by

yoneyjitca
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 71

Visit ebookball.

com to download the full version and


explore more ebook or textbook

Data Structures and Algorithms in Python 1st


Edition by Michael Goodrich, Roberto Tamassia,
Michael Goldwasser ISBN 9781118476734 1118476735

_____ Click the link below to download _____


https://ebookball.com/product/data-structures-and-
algorithms-in-python-1st-edition-by-michael-goodrich-
roberto-tamassia-michael-goldwasser-
isbn-9781118476734-1118476735-15762/

Explore and download more ebook or textbook at ebookball.com


Here are some recommended products that we believe you will be
interested in. You can click the link to download.

Data Structures Algorithms and Applications in C++ With


Microsoft Compiler 2nd edition by Michael Goodrich,
Roberto Tamassia, David Mount ISBN B005FHM6X2
978-0470383278
https://ebookball.com/product/data-structures-algorithms-and-
applications-in-c-with-microsoft-compiler-2nd-edition-by-michael-
goodrich-roberto-tamassia-david-mount-
isbn-b005fhm6x2-978-0470383278-16544/

Data Structures and Algorithms in Java 1st Edition by


Peter Drake ISBN 0131469142 9780131469143

https://ebookball.com/product/data-structures-and-algorithms-in-
java-1st-edition-by-peter-drake-isbn-0131469142-9780131469143-12422/

Data Structures and Algorithms in C 1st edition by Adam


Drozdek ASIN B002WLXMBY

https://ebookball.com/product/data-structures-and-algorithms-in-c-1st-
edition-by-adam-drozdek-asin-b002wlxmby-25076/

Data Structures Algorithms and Applications in C++ 1st


edition by Adam Drozdek ISBN 1133608426 9781133608424

https://ebookball.com/product/data-structures-algorithms-and-
applications-in-c-1st-edition-by-adam-drozdek-
isbn-1133608426-9781133608424-17250/
Data Structures and Algorithms 1st Edition by Alfred Aho
ISBN 0201000237 9780201000238

https://ebookball.com/product/data-structures-and-algorithms-1st-
edition-by-alfred-aho-isbn-0201000237-9780201000238-25072/

Programming Fundamentals Using MATLAB Analyze Data And


Develop Algorithms 1st Edition by Michael Weeks B09NZC2XC1

https://ebookball.com/product/programming-fundamentals-using-matlab-
analyze-data-and-develop-algorithms-1st-edition-by-michael-
weeks-b09nzc2xc1-17618/

Data Structures and Other Objects Using C++ 2nd edition by


Michael Main ISBN 8129705826 978-8129705822

https://ebookball.com/product/data-structures-and-other-objects-
using-c-2nd-edition-by-michael-main-
isbn-8129705826-978-8129705822-16344/

Think Data Structures Algorithms and Information Retrieval


in Java 1st Edition by Allen Downey ISBN 9781491972311
1491972319
https://ebookball.com/product/think-data-structures-algorithms-and-
information-retrieval-in-java-1st-edition-by-allen-downey-
isbn-9781491972311-1491972319-15760/

Problem Solving in Data Structures and Algorithms Using C


1st Edition by Hemant Jain ISBN 9352655915 9789352655915

https://ebookball.com/product/problem-solving-in-data-structures-and-
algorithms-using-c-1st-edition-by-hemant-jain-
isbn-9352655915-9789352655915-15768/
www.it-ebooks.info
www.it-ebooks.info
Data Structures and
Algorithms in Python
Michael T. Goodrich
Department of Computer Science
University of California, Irvine

Roberto Tamassia
Department of Computer Science
Brown University

Michael H. Goldwasser
Department of Mathematics and Computer Science
Saint Louis University

www.it-ebooks.info
VP & PUBLISHER Don Fowley
EXECUTIVE EDITOR Beth Lang Golub
EDITORIAL PROGRAM ASSISTANT Katherine Willis
MARKETING MANAGER Christopher Ruel
DESIGNER Kenji Ngieng
SENIOR PRODUCTION MANAGER Janis Soo
ASSOCIATE PRODUCTION MANAGER Joyce Poh

This book was set in LaTEX by the authors. Printed and bound by Courier Westford.
The cover was printed by Courier Westford.

This book is printed on acid free paper.

Founded in 1807, John Wiley & Sons, Inc. has been a valued source of knowledge and understanding for
more than 200 years, helping people around the world meet their needs and fulfill their aspirations. Our
company is built on a foundation of principles that include responsibility to the communities we serve and
where we live and work. In 2008, we launched a Corporate Citizenship Initiative, a global effort to address
the environmental, social, economic, and ethical challenges we face in our business. Among the issues we are
addressing are carbon impact, paper specifications and procurement, ethical conduct within our business and
among our vendors, and community and charitable support. For more information, please visit our website:
www.wiley.com/go/citizenship.

Copyright © 2013 John Wiley & Sons, Inc. All rights reserved. No part of this publication may be
reproduced, stored in a retrieval system or transmitted in any form or by any means, electronic, mechanical,
photocopying, recording, scanning or otherwise, except as permitted under Sections 107 or 108 of
the 1976 United States Copyright Act, without either the prior written permission of the Publisher, or
authorization through payment of the appropriate per-copy fee to the Copyright Clearance Center, Inc. 222
Rosewood Drive, Danvers, MA 01923, website www.copyright.com. Requests to the Publisher for permission
should be addressed to the Permissions Department, John Wiley & Sons, Inc., 111 River Street, Hoboken,
NJ 07030-5774, (201)748-6011, fax (201)748-6008, website http://www.wiley.com/go/permissions.

Evaluation copies are provided to qualified academics and professionals for review purposes only, for use
in their courses during the next academic year. These copies are licensed and may not be sold or transferred
to a third party. Upon completion of the review period, please return the evaluation copy to Wiley. Return
instructions and a free of charge return mailing label are available at www.wiley.com/go/returnlabel. If you
have chosen to adopt this textbook for use in your course, please accept this book as your complimentary desk
copy. Outside of the United States, please contact your local sales representative.

Printed in the United States of America

10 9 8 7 6 5 4 3 2 1

www.it-ebooks.info
To Karen, Paul, Anna, and Jack
– Michael T. Goodrich

To Isabel
– Roberto Tamassia

To Susan, Calista, and Maya


– Michael H. Goldwasser

www.it-ebooks.info
www.it-ebooks.info
Preface
The design and analysis of efficient data structures has long been recognized as a
vital subject in computing and is part of the core curriculum of computer science
and computer engineering undergraduate degrees. Data Structures and Algorithms
in Python provides an introduction to data structures and algorithms, including their
design, analysis, and implementation. This book is designed for use in a beginning-
level data structures course, or in an intermediate-level introduction to algorithms
course. We discuss its use for such courses in more detail later in this preface.
To promote the development of robust and reusable software, we have tried to
take a consistent object-oriented viewpoint throughout this text. One of the main
ideas of the object-oriented approach is that data should be presented as being en-
capsulated with the methods that access and modify them. That is, rather than
simply viewing data as a collection of bytes and addresses, we think of data ob-
jects as instances of an abstract data type (ADT), which includes a repertoire of
methods for performing operations on data objects of this type. We then empha-
size that there may be several different implementation strategies for a particular
ADT, and explore the relative pros and cons of these choices. We provide complete
Python implementations for almost all data structures and algorithms discussed,
and we introduce important object-oriented design patterns as means to organize
those implementations into reusable components.
Desired outcomes for readers of our book include that:
• They have knowledge of the most common abstractions for data collections
(e.g., stacks, queues, lists, trees, maps).
• They understand algorithmic strategies for producing efficient realizations of
common data structures.
• They can analyze algorithmic performance, both theoretically and experi-
mentally, and recognize common trade-offs between competing strategies.
• They can wisely use existing data structures and algorithms found in modern
programming language libraries.
• They have experience working with concrete implementations for most foun-
dational data structures and algorithms.
• They can apply data structures and algorithms to solve complex problems.
In support of the last goal, we present many example applications of data structures
throughout the book, including the processing of file systems, matching of tags
in structured formats such as HTML, simple cryptography, text frequency analy-
sis, automated geometric layout, Huffman coding, DNA sequence alignment, and
search engine indexing.

www.it-ebooks.info
vi Preface

Book Features
This book is based upon the book Data Structures and Algorithms in Java by
Goodrich and Tamassia, and the related Data Structures and Algorithms in C++
by Goodrich, Tamassia, and Mount. However, this book is not simply a translation
of those other books to Python. In adapting the material for this book, we have
significantly redesigned the organization and content of the book as follows:
• The code base has been entirely redesigned to take advantage of the features
of Python, such as use of generators for iterating elements of a collection.
• Many algorithms that were presented as pseudo-code in the Java and C++
versions are directly presented as complete Python code.
• In general, ADTs are defined to have consistent interface with Python’s built-
in data types and those in Python’s collections module.
• Chapter 5 provides an in-depth exploration of the dynamic array-based un-
derpinnings of Python’s built-in list, tuple, and str classes. New Appendix A
serves as an additional reference regarding the functionality of the str class.
• Over 450 illustrations have been created or revised.
• New and revised exercises bring the overall total number to 750.

Online Resources
This book is accompanied by an extensive set of online resources, which can be
found at the following Web site:
www.wiley.com/college/goodrich
Students are encouraged to use this site along with the book, to help with exer-
cises and increase understanding of the subject. Instructors are likewise welcome
to use the site to help plan, organize, and present their course materials. Included
on this Web site is a collection of educational aids that augment the topics of this
book, for both students and instructors. Because of their added value, some of these
online resources are password protected.
For all readers, and especially for students, we include the following resources:
• All the Python source code presented in this book.
• PDF handouts of Powerpoint slides (four-per-page) provided to instructors.
• A database of hints to all exercises, indexed by problem number.
For instructors using this book, we include the following additional teaching aids:
• Solutions to hundreds of the book’s exercises.
• Color versions of all figures and illustrations from the book.
• Slides in Powerpoint and PDF (one-per-page) format.
The slides are fully editable, so as to allow an instructor using this book full free-
dom in customizing his or her presentations. All the online resources are provided
at no extra charge to any instructor adopting this book for his or her course.

www.it-ebooks.info
Preface vii

Contents and Organization


The chapters for this book are organized to provide a pedagogical path that starts
with the basics of Python programming and object-oriented design. We then add
foundational techniques like algorithm analysis and recursion. In the main portion
of the book, we present fundamental data structures and algorithms, concluding
with a discussion of memory management (that is, the architectural underpinnings
of data structures). Specifically, the chapters for this book are organized as follows:
1. Python Primer
2. Object-Oriented Programming
3. Algorithm Analysis
4. Recursion
5. Array-Based Sequences
6. Stacks, Queues, and Deques
7. Linked Lists
8. Trees
9. Priority Queues
10. Maps, Hash Tables, and Skip Lists
11. Search Trees
12. Sorting and Selection
13. Text Processing
14. Graph Algorithms
15. Memory Management and B-Trees
A. Character Strings in Python
B. Useful Mathematical Facts
A more detailed table of contents follows this preface, beginning on page xi.

Prerequisites
We assume that the reader is at least vaguely familiar with a high-level program-
ming language, such as C, C++, Python, or Java, and that he or she understands the
main constructs from such a high-level language, including:
• Variables and expressions.
• Decision structures (such as if-statements and switch-statements).
• Iteration structures (for loops and while loops).
• Functions (whether stand-alone or object-oriented methods).
For readers who are familiar with these concepts, but not with how they are ex-
pressed in Python, we provide a primer on the Python language in Chapter 1. Still,
this book is primarily a data structures book, not a Python book; hence, it does not
give a comprehensive treatment of Python.

www.it-ebooks.info
viii Preface
We delay treatment of object-oriented programming in Python until Chapter 2.
This chapter is useful for those new to Python, and for those who may be familiar
with Python, yet not with object-oriented programming.
In terms of mathematical background, we assume the reader is somewhat famil-
iar with topics from high-school mathematics. Even so, in Chapter 3, we discuss
the seven most-important functions for algorithm analysis. In fact, sections that use
something other than one of these seven functions are considered optional, and are
indicated with a star (). We give a summary of other useful mathematical facts,
including elementary probability, in Appendix B.

Relation to Computer Science Curriculum


To assist instructors in designing a course in the context of the IEEE/ACM 2013
Computing Curriculum, the following table describes curricular knowledge units
that are covered within this book.

Knowledge Unit Relevant Material


AL/Basic Analysis Chapter 3 and Sections 4.2 & 12.2.4
AL/Algorithmic Strategies Sections 12.2.1, 13.2.1, 13.3, & 13.4.2
AL/Fundamental Data Structures Sections 4.1.3, 5.5.2, 9.4.1, 9.3, 10.2, 11.1, 13.2,
and Algorithms Chapter 12 & much of Chapter 14
Sections 5.3, 10.4, 11.2 through 11.6, 12.3.1,
AL/Advanced Data Structures
13.5, 14.5.1, & 15.3
AR/Memory System Organization Chapter 15
and Architecture
DS/Sets, Relations and Functions Sections 10.5.1, 10.5.2, & 9.4
DS/Proof Techniques Sections 3.4, 4.2, 5.3.2, 9.3.6, & 12.4.1
DS/Basics of Counting Sections 2.4.2, 6.2.2, 12.2.4, 8.2.2 & Appendix B
DS/Graphs and Trees Much of Chapters 8 and 14
DS/Discrete Probability Sections 1.11.1, 10.2, 10.4.2, & 12.3.1
Much of the book, yet especially Chapter 2 and
PL/Object-Oriented Programming
Sections 7.4, 9.5.1, 10.1.3, & 11.2.1
PL/Functional Programming Section 1.10
SDF/Algorithms and Design Sections 2.1, 3.3, & 12.2.1
SDF/Fundamental Programming Chapters 1 & 4
Concepts
Chapters 6 & 7, Appendix A, and Sections 1.2.1,
SDF/Fundamental Data Structures
5.2, 5.4, 9.1, & 10.1
SDF/Developmental Methods Sections 1.7 & 2.2
SE/Software Design Sections 2.1 & 2.1.3
Mapping IEEE/ACM 2013 Computing Curriculum knowledge units to coverage in
this book.

www.it-ebooks.info
Preface ix

About the Authors


Michael Goodrich received his Ph.D. in Computer Science from Purdue University
in 1987. He is currently a Chancellor’s Professor in the Department of Computer
Science at University of California, Irvine. Previously, he was a professor at Johns
Hopkins University. He is a Fulbright Scholar and a Fellow of the American As-
sociation for the Advancement of Science (AAAS), Association for Computing
Machinery (ACM), and Institute of Electrical and Electronics Engineers (IEEE).
He is a recipient of the IEEE Computer Society Technical Achievement Award,
the ACM Recognition of Service Award, and the Pond Award for Excellence in
Undergraduate Teaching.
Roberto Tamassia received his Ph.D. in Electrical and Computer Engineering
from the University of Illinois at Urbana-Champaign in 1988. He is the Plastech
Professor of Computer Science and the Chair of the Department of Computer Sci-
ence at Brown University. He is also the Director of Brown’s Center for Geometric
Computing. His research interests include information security, cryptography, anal-
ysis, design, and implementation of algorithms, graph drawing and computational
geometry. He is a Fellow of the American Association for the Advancement of
Science (AAAS), Association for Computing Machinery (ACM) and Institute for
Electrical and Electronic Engineers (IEEE). He is also a recipient of the Technical
Achievement Award from the IEEE Computer Society.
Michael Goldwasser received his Ph.D. in Computer Science from Stanford
University in 1997. He is currently a Professor in the Department of Mathematics
and Computer Science at Saint Louis University and the Director of their Com-
puter Science program. Previously, he was a faculty member in the Department
of Computer Science at Loyola University Chicago. His research interests focus
on the design and implementation of algorithms, having published work involving
approximation algorithms, online computation, computational biology, and compu-
tational geometry. He is also active in the computer science education community.

Additional Books by These Authors


• M.T. Goodrich and R. Tamassia, Data Structures and Algorithms in Java, Wiley.
• M.T. Goodrich, R. Tamassia, and D.M. Mount, Data Structures and Algorithms
in C++, Wiley.
• M.T. Goodrich and R. Tamassia, Algorithm Design: Foundations, Analysis, and
Internet Examples, Wiley.
• M.T. Goodrich and R. Tamassia, Introduction to Computer Security, Addison-
Wesley.
• M.H. Goldwasser and D. Letscher, Object-Oriented Programming in Python,
Prentice Hall.

www.it-ebooks.info
x Preface

Acknowledgments
We have depended greatly upon the contributions of many individuals as part of
the development of this book. We begin by acknowledging the wonderful team at
Wiley. We are grateful to our editor, Beth Golub, for her enthusiastic support of
this project, from beginning to end. The efforts of Elizabeth Mills and Katherine
Willis were critical in keeping the project moving, from its early stages as an initial
proposal, through the extensive peer review process. We greatly appreciate the
attention to detail demonstrated by Julie Kennedy, the copyeditor for this book.
Finally, many thanks are due to Joyce Poh for managing the final months of the
production process.
We are truly indebted to the outside reviewers and readers for their copious
comments, emails, and constructive criticism, which were extremely useful in writ-
ing this edition. We therefore thank the following reviewers for their comments and
suggestions: Claude Anderson (Rose Hulman Institute of Technology), Alistair
Campbell (Hamilton College), Barry Cohen (New Jersey Institute of Technology),
Robert Franks (Central College), Andrew Harrington (Loyola University Chicago),
Dave Musicant (Carleton College), and Victor Norman (Calvin College). We wish
to particularly acknowledge Claude for going above and beyond the call of duty,
providing us with an enumeration of 400 detailed corrections or suggestions.
We thank David Mount, of University of Maryland, for graciously sharing the
wisdom gained from his experience with the C++ version of this text. We are grate-
ful to Erin Chambers and David Letscher, of Saint Louis University, for their intan-
gible contributions during many hallway conversations about the teaching of data
structures, and to David for comments on early versions of the Python code base for
this book. We thank David Zampino, a student at Loyola University Chicago, for
his feedback while using a draft of this book during an independent study course,
and to Andrew Harrington for supervising David’s studies.
We also wish to reiterate our thanks to the many research collaborators and
teaching assistants whose feedback shaped the previous Java and C++ versions of
this material. The benefits of those contributions carry forward to this book.
Finally, we would like to warmly thank Susan Goldwasser, Isabel Cruz, Karen
Goodrich, Giuseppe Di Battista, Franco Preparata, Ioannis Tollis, and our parents
for providing advice, encouragement, and support at various stages of the prepa-
ration of this book, and Calista and Maya Goldwasser for offering their advice
regarding the artistic merits of many illustrations. More importantly, we thank all
of these people for reminding us that there are things in life beyond writing books.

Michael T. Goodrich
Roberto Tamassia
Michael H. Goldwasser

www.it-ebooks.info
Contents

Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . v

1 Python Primer 1
1.1 Python Overview . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.1.1 The Python Interpreter . . . . . . . . . . . . . . . . . . 2
1.1.2 Preview of a Python Program . . . . . . . . . . . . . . 3
1.2 Objects in Python . . . . . . . . . . . . . . . . . . . . . . . . 4
1.2.1 Identifiers, Objects, and the Assignment Statement . . . 4
1.2.2 Creating and Using Objects . . . . . . . . . . . . . . . . 6
1.2.3 Python’s Built-In Classes . . . . . . . . . . . . . . . . . 7
1.3 Expressions, Operators, and Precedence . . . . . . . . . . . 12
1.3.1 Compound Expressions and Operator Precedence . . . . 17
1.4 Control Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.4.1 Conditionals . . . . . . . . . . . . . . . . . . . . . . . . 18
1.4.2 Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.5 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
1.5.1 Information Passing . . . . . . . . . . . . . . . . . . . . 24
1.5.2 Python’s Built-In Functions . . . . . . . . . . . . . . . . 28
1.6 Simple Input and Output . . . . . . . . . . . . . . . . . . . . 30
1.6.1 Console Input and Output . . . . . . . . . . . . . . . . 30
1.6.2 Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
1.7 Exception Handling . . . . . . . . . . . . . . . . . . . . . . . 33
1.7.1 Raising an Exception . . . . . . . . . . . . . . . . . . . 34
1.7.2 Catching an Exception . . . . . . . . . . . . . . . . . . 36
1.8 Iterators and Generators . . . . . . . . . . . . . . . . . . . . 39
1.9 Additional Python Conveniences . . . . . . . . . . . . . . . . 42
1.9.1 Conditional Expressions . . . . . . . . . . . . . . . . . . 42
1.9.2 Comprehension Syntax . . . . . . . . . . . . . . . . . . 43
1.9.3 Packing and Unpacking of Sequences . . . . . . . . . . 44
1.10 Scopes and Namespaces . . . . . . . . . . . . . . . . . . . . 46
1.11 Modules and the Import Statement . . . . . . . . . . . . . . 48
1.11.1 Existing Modules . . . . . . . . . . . . . . . . . . . . . 49
1.12 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
xi

www.it-ebooks.info
xii Contents
2 Object-Oriented Programming 56
2.1 Goals, Principles, and Patterns . . . . . . . . . . . . . . . . 57
2.1.1 Object-Oriented Design Goals . . . . . . . . . . . . . . 57
2.1.2 Object-Oriented Design Principles . . . . . . . . . . . . 58
2.1.3 Design Patterns . . . . . . . . . . . . . . . . . . . . . . 61
2.2 Software Development . . . . . . . . . . . . . . . . . . . . . 62
2.2.1 Design . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
2.2.2 Pseudo-Code . . . . . . . . . . . . . . . . . . . . . . . 64
2.2.3 Coding Style and Documentation . . . . . . . . . . . . . 64
2.2.4 Testing and Debugging . . . . . . . . . . . . . . . . . . 67
2.3 Class Definitions . . . . . . . . . . . . . . . . . . . . . . . . . 69
2.3.1 Example: CreditCard Class . . . . . . . . . . . . . . . . 69
2.3.2 Operator Overloading and Python’s Special Methods . . 74
2.3.3 Example: Multidimensional Vector Class . . . . . . . . . 77
2.3.4 Iterators . . . . . . . . . . . . . . . . . . . . . . . . . . 79
2.3.5 Example: Range Class . . . . . . . . . . . . . . . . . . . 80
2.4 Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
2.4.1 Extending the CreditCard Class . . . . . . . . . . . . . . 83
2.4.2 Hierarchy of Numeric Progressions . . . . . . . . . . . . 87
2.4.3 Abstract Base Classes . . . . . . . . . . . . . . . . . . . 93
2.5 Namespaces and Object-Orientation . . . . . . . . . . . . . 96
2.5.1 Instance and Class Namespaces . . . . . . . . . . . . . . 96
2.5.2 Name Resolution and Dynamic Dispatch . . . . . . . . . 100
2.6 Shallow and Deep Copying . . . . . . . . . . . . . . . . . . . 101
2.7 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103

3 Algorithm Analysis 109


3.1 Experimental Studies . . . . . . . . . . . . . . . . . . . . . . 111
3.1.1 Moving Beyond Experimental Analysis . . . . . . . . . . 113
3.2 The Seven Functions Used in This Book . . . . . . . . . . . 115
3.2.1 Comparing Growth Rates . . . . . . . . . . . . . . . . . 122
3.3 Asymptotic Analysis . . . . . . . . . . . . . . . . . . . . . . . 123
3.3.1 The “Big-Oh” Notation . . . . . . . . . . . . . . . . . . 123
3.3.2 Comparative Analysis . . . . . . . . . . . . . . . . . . . 128
3.3.3 Examples of Algorithm Analysis . . . . . . . . . . . . . 130
3.4 Simple Justification Techniques . . . . . . . . . . . . . . . . 137
3.4.1 By Example . . . . . . . . . . . . . . . . . . . . . . . . 137
3.4.2 The “Contra” Attack . . . . . . . . . . . . . . . . . . . 137
3.4.3 Induction and Loop Invariants . . . . . . . . . . . . . . 138
3.5 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141

www.it-ebooks.info
Contents xiii
4 Recursion 148
4.1 Illustrative Examples . . . . . . . . . . . . . . . . . . . . . . 150
4.1.1 The Factorial Function . . . . . . . . . . . . . . . . . . 150
4.1.2 Drawing an English Ruler . . . . . . . . . . . . . . . . . 152
4.1.3 Binary Search . . . . . . . . . . . . . . . . . . . . . . . 155
4.1.4 File Systems . . . . . . . . . . . . . . . . . . . . . . . . 157
4.2 Analyzing Recursive Algorithms . . . . . . . . . . . . . . . . 161
4.3 Recursion Run Amok . . . . . . . . . . . . . . . . . . . . . . 165
4.3.1 Maximum Recursive Depth in Python . . . . . . . . . . 168
4.4 Further Examples of Recursion . . . . . . . . . . . . . . . . . 169
4.4.1 Linear Recursion . . . . . . . . . . . . . . . . . . . . . . 169
4.4.2 Binary Recursion . . . . . . . . . . . . . . . . . . . . . 174
4.4.3 Multiple Recursion . . . . . . . . . . . . . . . . . . . . 175
4.5 Designing Recursive Algorithms . . . . . . . . . . . . . . . . 177
4.6 Eliminating Tail Recursion . . . . . . . . . . . . . . . . . . . 178
4.7 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180

5 Array-Based Sequences 183


5.1 Python’s Sequence Types . . . . . . . . . . . . . . . . . . . . 184
5.2 Low-Level Arrays . . . . . . . . . . . . . . . . . . . . . . . . . 185
5.2.1 Referential Arrays . . . . . . . . . . . . . . . . . . . . . 187
5.2.2 Compact Arrays in Python . . . . . . . . . . . . . . . . 190
5.3 Dynamic Arrays and Amortization . . . . . . . . . . . . . . . 192
5.3.1 Implementing a Dynamic Array . . . . . . . . . . . . . . 195
5.3.2 Amortized Analysis of Dynamic Arrays . . . . . . . . . . 197
5.3.3 Python’s List Class . . . . . . . . . . . . . . . . . . . . 201
5.4 Efficiency of Python’s Sequence Types . . . . . . . . . . . . 202
5.4.1 Python’s List and Tuple Classes . . . . . . . . . . . . . 202
5.4.2 Python’s String Class . . . . . . . . . . . . . . . . . . . 208
5.5 Using Array-Based Sequences . . . . . . . . . . . . . . . . . 210
5.5.1 Storing High Scores for a Game . . . . . . . . . . . . . 210
5.5.2 Sorting a Sequence . . . . . . . . . . . . . . . . . . . . 214
5.5.3 Simple Cryptography . . . . . . . . . . . . . . . . . . . 216
5.6 Multidimensional Data Sets . . . . . . . . . . . . . . . . . . 219
5.7 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224

6 Stacks, Queues, and Deques 228


6.1 Stacks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
6.1.1 The Stack Abstract Data Type . . . . . . . . . . . . . . 230
6.1.2 Simple Array-Based Stack Implementation . . . . . . . . 231
6.1.3 Reversing Data Using a Stack . . . . . . . . . . . . . . 235
6.1.4 Matching Parentheses and HTML Tags . . . . . . . . . 236

www.it-ebooks.info
xiv Contents
6.2 Queues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
6.2.1 The Queue Abstract Data Type . . . . . . . . . . . . . 240
6.2.2 Array-Based Queue Implementation . . . . . . . . . . . 241
6.3 Double-Ended Queues . . . . . . . . . . . . . . . . . . . . . . 247
6.3.1 The Deque Abstract Data Type . . . . . . . . . . . . . 247
6.3.2 Implementing a Deque with a Circular Array . . . . . . . 248
6.3.3 Deques in the Python Collections Module . . . . . . . . 249
6.4 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250

7 Linked Lists 255


7.1 Singly Linked Lists . . . . . . . . . . . . . . . . . . . . . . . . 256
7.1.1 Implementing a Stack with a Singly Linked List . . . . . 261
7.1.2 Implementing a Queue with a Singly Linked List . . . . . 264
7.2 Circularly Linked Lists . . . . . . . . . . . . . . . . . . . . . . 266
7.2.1 Round-Robin Schedulers . . . . . . . . . . . . . . . . . 267
7.2.2 Implementing a Queue with a Circularly Linked List . . . 268
7.3 Doubly Linked Lists . . . . . . . . . . . . . . . . . . . . . . . 270
7.3.1 Basic Implementation of a Doubly Linked List . . . . . . 273
7.3.2 Implementing a Deque with a Doubly Linked List . . . . 275
7.4 The Positional List ADT . . . . . . . . . . . . . . . . . . . . 277
7.4.1 The Positional List Abstract Data Type . . . . . . . . . 279
7.4.2 Doubly Linked List Implementation . . . . . . . . . . . . 281
7.5 Sorting a Positional List . . . . . . . . . . . . . . . . . . . . 285
7.6 Case Study: Maintaining Access Frequencies . . . . . . . . 286
7.6.1 Using a Sorted List . . . . . . . . . . . . . . . . . . . . 286
7.6.2 Using a List with the Move-to-Front Heuristic . . . . . . 289
7.7 Link-Based vs. Array-Based Sequences . . . . . . . . . . . . 292
7.8 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294

8 Trees 299
8.1 General Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
8.1.1 Tree Definitions and Properties . . . . . . . . . . . . . . 301
8.1.2 The Tree Abstract Data Type . . . . . . . . . . . . . . 305
8.1.3 Computing Depth and Height . . . . . . . . . . . . . . . 308
8.2 Binary Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . 311
8.2.1 The Binary Tree Abstract Data Type . . . . . . . . . . . 313
8.2.2 Properties of Binary Trees . . . . . . . . . . . . . . . . 315
8.3 Implementing Trees . . . . . . . . . . . . . . . . . . . . . . . 317
8.3.1 Linked Structure for Binary Trees . . . . . . . . . . . . . 317
8.3.2 Array-Based Representation of a Binary Tree . . . . . . 325
8.3.3 Linked Structure for General Trees . . . . . . . . . . . . 327
8.4 Tree Traversal Algorithms . . . . . . . . . . . . . . . . . . . 328

www.it-ebooks.info
Contents xv
8.4.1 Preorder and Postorder Traversals of General Trees . . . 328
8.4.2 Breadth-First Tree Traversal . . . . . . . . . . . . . . . 330
8.4.3 Inorder Traversal of a Binary Tree . . . . . . . . . . . . 331
8.4.4 Implementing Tree Traversals in Python . . . . . . . . . 333
8.4.5 Applications of Tree Traversals . . . . . . . . . . . . . . 337
8.4.6 Euler Tours and the Template Method Pattern  . . . . 341
8.5 Case Study: An Expression Tree . . . . . . . . . . . . . . . . 348
8.6 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352

9 Priority Queues 362


9.1 The Priority Queue Abstract Data Type . . . . . . . . . . . 363
9.1.1 Priorities . . . . . . . . . . . . . . . . . . . . . . . . . . 363
9.1.2 The Priority Queue ADT . . . . . . . . . . . . . . . . . 364
9.2 Implementing a Priority Queue . . . . . . . . . . . . . . . . 365
9.2.1 The Composition Design Pattern . . . . . . . . . . . . . 365
9.2.2 Implementation with an Unsorted List . . . . . . . . . . 366
9.2.3 Implementation with a Sorted List . . . . . . . . . . . . 368
9.3 Heaps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370
9.3.1 The Heap Data Structure . . . . . . . . . . . . . . . . . 370
9.3.2 Implementing a Priority Queue with a Heap . . . . . . . 372
9.3.3 Array-Based Representation of a Complete Binary Tree . 376
9.3.4 Python Heap Implementation . . . . . . . . . . . . . . . 376
9.3.5 Analysis of a Heap-Based Priority Queue . . . . . . . . . 379
9.3.6 Bottom-Up Heap Construction  . . . . . . . . . . . . . 380
9.3.7 Python’s heapq Module . . . . . . . . . . . . . . . . . . 384
9.4 Sorting with a Priority Queue . . . . . . . . . . . . . . . . . 385
9.4.1 Selection-Sort and Insertion-Sort . . . . . . . . . . . . . 386
9.4.2 Heap-Sort . . . . . . . . . . . . . . . . . . . . . . . . . 388
9.5 Adaptable Priority Queues . . . . . . . . . . . . . . . . . . . 390
9.5.1 Locators . . . . . . . . . . . . . . . . . . . . . . . . . . 390
9.5.2 Implementing an Adaptable Priority Queue . . . . . . . 391
9.6 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 395

10 Maps, Hash Tables, and Skip Lists 401


10.1 Maps and Dictionaries . . . . . . . . . . . . . . . . . . . . . 402
10.1.1 The Map ADT . . . . . . . . . . . . . . . . . . . . . . 403
10.1.2 Application: Counting Word Frequencies . . . . . . . . . 405
10.1.3 Python’s MutableMapping Abstract Base Class . . . . . 406
10.1.4 Our MapBase Class . . . . . . . . . . . . . . . . . . . . 407
10.1.5 Simple Unsorted Map Implementation . . . . . . . . . . 408
10.2 Hash Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . 410
10.2.1 Hash Functions . . . . . . . . . . . . . . . . . . . . . . 411

www.it-ebooks.info
xvi Contents
10.2.2 Collision-Handling Schemes . . . . . . . . . . . . . . . . 417
10.2.3 Load Factors, Rehashing, and Efficiency . . . . . . . . . 420
10.2.4 Python Hash Table Implementation . . . . . . . . . . . 422
10.3 Sorted Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . 427
10.3.1 Sorted Search Tables . . . . . . . . . . . . . . . . . . . 428
10.3.2 Two Applications of Sorted Maps . . . . . . . . . . . . 434
10.4 Skip Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 437
10.4.1 Search and Update Operations in a Skip List . . . . . . 439
10.4.2 Probabilistic Analysis of Skip Lists  . . . . . . . . . . . 443
10.5 Sets, Multisets, and Multimaps . . . . . . . . . . . . . . . . 446
10.5.1 The Set ADT . . . . . . . . . . . . . . . . . . . . . . . 446
10.5.2 Python’s MutableSet Abstract Base Class . . . . . . . . 448
10.5.3 Implementing Sets, Multisets, and Multimaps . . . . . . 450
10.6 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452

11 Search Trees 459


11.1 Binary Search Trees . . . . . . . . . . . . . . . . . . . . . . . 460
11.1.1 Navigating a Binary Search Tree . . . . . . . . . . . . . 461
11.1.2 Searches . . . . . . . . . . . . . . . . . . . . . . . . . . 463
11.1.3 Insertions and Deletions . . . . . . . . . . . . . . . . . . 465
11.1.4 Python Implementation . . . . . . . . . . . . . . . . . . 468
11.1.5 Performance of a Binary Search Tree . . . . . . . . . . . 473
11.2 Balanced Search Trees . . . . . . . . . . . . . . . . . . . . . 475
11.2.1 Python Framework for Balancing Search Trees . . . . . . 478
11.3 AVL Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 481
11.3.1 Update Operations . . . . . . . . . . . . . . . . . . . . 483
11.3.2 Python Implementation . . . . . . . . . . . . . . . . . . 488
11.4 Splay Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . 490
11.4.1 Splaying . . . . . . . . . . . . . . . . . . . . . . . . . . 490
11.4.2 When to Splay . . . . . . . . . . . . . . . . . . . . . . . 494
11.4.3 Python Implementation . . . . . . . . . . . . . . . . . . 496
11.4.4 Amortized Analysis of Splaying  . . . . . . . . . . . . 497
11.5 (2,4) Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . 502
11.5.1 Multiway Search Trees . . . . . . . . . . . . . . . . . . 502
11.5.2 (2,4)-Tree Operations . . . . . . . . . . . . . . . . . . . 505
11.6 Red-Black Trees . . . . . . . . . . . . . . . . . . . . . . . . . 512
11.6.1 Red-Black Tree Operations . . . . . . . . . . . . . . . . 514
11.6.2 Python Implementation . . . . . . . . . . . . . . . . . . 525
11.7 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 528

www.it-ebooks.info
Contents xvii
12 Sorting and Selection 536
12.1 Why Study Sorting Algorithms? . . . . . . . . . . . . . . . . 537
12.2 Merge-Sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538
12.2.1 Divide-and-Conquer . . . . . . . . . . . . . . . . . . . . 538
12.2.2 Array-Based Implementation of Merge-Sort . . . . . . . 543
12.2.3 The Running Time of Merge-Sort . . . . . . . . . . . . 544
12.2.4 Merge-Sort and Recurrence Equations  . . . . . . . . . 546
12.2.5 Alternative Implementations of Merge-Sort . . . . . . . 547
12.3 Quick-Sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . 550
12.3.1 Randomized Quick-Sort . . . . . . . . . . . . . . . . . . 557
12.3.2 Additional Optimizations for Quick-Sort . . . . . . . . . 559
12.4 Studying Sorting through an Algorithmic Lens . . . . . . . 562
12.4.1 Lower Bound for Sorting . . . . . . . . . . . . . . . . . 562
12.4.2 Linear-Time Sorting: Bucket-Sort and Radix-Sort . . . . 564
12.5 Comparing Sorting Algorithms . . . . . . . . . . . . . . . . . 567
12.6 Python’s Built-In Sorting Functions . . . . . . . . . . . . . . 569
12.6.1 Sorting According to a Key Function . . . . . . . . . . . 569
12.7 Selection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 571
12.7.1 Prune-and-Search . . . . . . . . . . . . . . . . . . . . . 571
12.7.2 Randomized Quick-Select . . . . . . . . . . . . . . . . . 572
12.7.3 Analyzing Randomized Quick-Select . . . . . . . . . . . 573
12.8 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 574

13 Text Processing 581


13.1 Abundance of Digitized Text . . . . . . . . . . . . . . . . . . 582
13.1.1 Notations for Strings and the Python str Class . . . . . . 583
13.2 Pattern-Matching Algorithms . . . . . . . . . . . . . . . . . 584
13.2.1 Brute Force . . . . . . . . . . . . . . . . . . . . . . . . 584
13.2.2 The Boyer-Moore Algorithm . . . . . . . . . . . . . . . 586
13.2.3 The Knuth-Morris-Pratt Algorithm . . . . . . . . . . . . 590
13.3 Dynamic Programming . . . . . . . . . . . . . . . . . . . . . 594
13.3.1 Matrix Chain-Product . . . . . . . . . . . . . . . . . . . 594
13.3.2 DNA and Text Sequence Alignment . . . . . . . . . . . 597
13.4 Text Compression and the Greedy Method . . . . . . . . . 601
13.4.1 The Huffman Coding Algorithm . . . . . . . . . . . . . 602
13.4.2 The Greedy Method . . . . . . . . . . . . . . . . . . . . 603
13.5 Tries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 604
13.5.1 Standard Tries . . . . . . . . . . . . . . . . . . . . . . . 604
13.5.2 Compressed Tries . . . . . . . . . . . . . . . . . . . . . 608
13.5.3 Suffix Tries . . . . . . . . . . . . . . . . . . . . . . . . 610
13.5.4 Search Engine Indexing . . . . . . . . . . . . . . . . . . 612

www.it-ebooks.info
xviii Contents
13.6 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 613

14 Graph Algorithms 619


14.1 Graphs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 620
14.1.1 The Graph ADT . . . . . . . . . . . . . . . . . . . . . . 626
14.2 Data Structures for Graphs . . . . . . . . . . . . . . . . . . . 627
14.2.1 Edge List Structure . . . . . . . . . . . . . . . . . . . . 628
14.2.2 Adjacency List Structure . . . . . . . . . . . . . . . . . 630
14.2.3 Adjacency Map Structure . . . . . . . . . . . . . . . . . 632
14.2.4 Adjacency Matrix Structure . . . . . . . . . . . . . . . . 633
14.2.5 Python Implementation . . . . . . . . . . . . . . . . . . 634
14.3 Graph Traversals . . . . . . . . . . . . . . . . . . . . . . . . . 638
14.3.1 Depth-First Search . . . . . . . . . . . . . . . . . . . . 639
14.3.2 DFS Implementation and Extensions . . . . . . . . . . . 644
14.3.3 Breadth-First Search . . . . . . . . . . . . . . . . . . . 648
14.4 Transitive Closure . . . . . . . . . . . . . . . . . . . . . . . . 651
14.5 Directed Acyclic Graphs . . . . . . . . . . . . . . . . . . . . 655
14.5.1 Topological Ordering . . . . . . . . . . . . . . . . . . . 655
14.6 Shortest Paths . . . . . . . . . . . . . . . . . . . . . . . . . . 659
14.6.1 Weighted Graphs . . . . . . . . . . . . . . . . . . . . . 659
14.6.2 Dijkstra’s Algorithm . . . . . . . . . . . . . . . . . . . . 661
14.7 Minimum Spanning Trees . . . . . . . . . . . . . . . . . . . . 670
14.7.1 Prim-Jarnı́k Algorithm . . . . . . . . . . . . . . . . . . 672
14.7.2 Kruskal’s Algorithm . . . . . . . . . . . . . . . . . . . . 676
14.7.3 Disjoint Partitions and Union-Find Structures . . . . . . 681
14.8 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 686

15 Memory Management and B-Trees 697


15.1 Memory Management . . . . . . . . . . . . . . . . . . . . . . 698
15.1.1 Memory Allocation . . . . . . . . . . . . . . . . . . . . 699
15.1.2 Garbage Collection . . . . . . . . . . . . . . . . . . . . 700
15.1.3 Additional Memory Used by the Python Interpreter . . . 703
15.2 Memory Hierarchies and Caching . . . . . . . . . . . . . . . 705
15.2.1 Memory Systems . . . . . . . . . . . . . . . . . . . . . 705
15.2.2 Caching Strategies . . . . . . . . . . . . . . . . . . . . 706
15.3 External Searching and B-Trees . . . . . . . . . . . . . . . . 711
15.3.1 (a,b) Trees . . . . . . . . . . . . . . . . . . . . . . . . . 712
15.3.2 B-Trees . . . . . . . . . . . . . . . . . . . . . . . . . . 714
15.4 External-Memory Sorting . . . . . . . . . . . . . . . . . . . . 715
15.4.1 Multiway Merging . . . . . . . . . . . . . . . . . . . . . 716
15.5 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 717

www.it-ebooks.info
Contents xix
A Character Strings in Python 721

B Useful Mathematical Facts 725

Bibliography 732

Index 737

www.it-ebooks.info
www.it-ebooks.info
Chapter

1
Contents
Python Primer

1.1 Python Overview . . . . . . . . . . . . . . . . . . . . . . . . 2


1.1.1 The Python Interpreter . . . . . . . . . . . . . . . . . . . 2
1.1.2 Preview of a Python Program . . . . . . . . . . . . . . . 3
1.2 Objects in Python . . . . . . . . . . . . . . . . . . . . . . . 4
1.2.1 Identifiers, Objects, and the Assignment Statement . . . . 4
1.2.2 Creating and Using Objects . . . . . . . . . . . . . . . . . 6
1.2.3 Python’s Built-In Classes . . . . . . . . . . . . . . . . . . 7
1.3 Expressions, Operators, and Precedence . . . . . . . . . . . 12
1.3.1 Compound Expressions and Operator Precedence . . . . . 17
1.4 Control Flow . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.4.1 Conditionals . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.4.2 Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.5 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
1.5.1 Information Passing . . . . . . . . . . . . . . . . . . . . . 24
1.5.2 Python’s Built-In Functions . . . . . . . . . . . . . . . . . 28
1.6 Simple Input and Output . . . . . . . . . . . . . . . . . . . 30
1.6.1 Console Input and Output . . . . . . . . . . . . . . . . . 30
1.6.2 Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
1.7 Exception Handling . . . . . . . . . . . . . . . . . . . . . . 33
1.7.1 Raising an Exception . . . . . . . . . . . . . . . . . . . . 34
1.7.2 Catching an Exception . . . . . . . . . . . . . . . . . . . 36
1.8 Iterators and Generators . . . . . . . . . . . . . . . . . . . 39
1.9 Additional Python Conveniences . . . . . . . . . . . . . . . 42
1.9.1 Conditional Expressions . . . . . . . . . . . . . . . . . . . 42
1.9.2 Comprehension Syntax . . . . . . . . . . . . . . . . . . . 43
1.9.3 Packing and Unpacking of Sequences . . . . . . . . . . . 44
1.10 Scopes and Namespaces . . . . . . . . . . . . . . . . . . . 46
1.11 Modules and the Import Statement . . . . . . . . . . . . . 48
1.11.1 Existing Modules . . . . . . . . . . . . . . . . . . . . . . 49
1.12 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

www.it-ebooks.info
2 Chapter 1. Python Primer

1.1 Python Overview


Building data structures and algorithms requires that we communicate detailed in-
structions to a computer. An excellent way to perform such communications is
using a high-level computer language, such as Python. The Python programming
language was originally developed by Guido van Rossum in the early 1990s, and
has since become a prominently used language in industry and education. The sec-
ond major version of the language, Python 2, was released in 2000, and the third
major version, Python 3, released in 2008. We note that there are significant in-
compatibilities between Python 2 and Python 3. This book is based on Python 3
(more specifically, Python 3.1 or later). The latest version of the language is freely
available at www.python.org, along with documentation and tutorials.
In this chapter, we provide an overview of the Python programming language,
and we continue this discussion in the next chapter, focusing on object-oriented
principles. We assume that readers of this book have prior programming experi-
ence, although not necessarily using Python. This book does not provide a com-
plete description of the Python language (there are numerous language references
for that purpose), but it does introduce all aspects of the language that are used in
code fragments later in this book.

1.1.1 The Python Interpreter


Python is formally an interpreted language. Commands are executed through a
piece of software known as the Python interpreter. The interpreter receives a com-
mand, evaluates that command, and reports the result of the command. While the
interpreter can be used interactively (especially when debugging), a programmer
typically defines a series of commands in advance and saves those commands in a
plain text file known as source code or a script. For Python, source code is conven-
tionally stored in a file named with the .py suffix (e.g., demo.py).
On most operating systems, the Python interpreter can be started by typing
python from the command line. By default, the interpreter starts in interactive
mode with a clean workspace. Commands from a predefined script saved in a
file (e.g., demo.py) are executed by invoking the interpreter with the filename as
an argument (e.g., python demo.py), or using an additional -i flag in order to
execute a script and then enter interactive mode (e.g., python -i demo.py).
Many integrated development environments (IDEs) provide richer software
development platforms for Python, including one named IDLE that is included
with the standard Python distribution. IDLE provides an embedded text-editor with
support for displaying and editing Python code, and a basic debugger, allowing
step-by-step execution of a program while examining key variable values.

www.it-ebooks.info
1.1. Python Overview 3

1.1.2 Preview of a Python Program


As a simple introduction, Code Fragment 1.1 presents a Python program that com-
putes the grade-point average (GPA) for a student based on letter grades that are
entered by a user. Many of the techniques demonstrated in this example will be
discussed in the remainder of this chapter. At this point, we draw attention to a few
high-level issues, for readers who are new to Python as a programming language.
Python’s syntax relies heavily on the use of whitespace. Individual statements
are typically concluded with a newline character, although a command can extend
to another line, either with a concluding backslash character (\), or if an opening
delimiter has not yet been closed, such as the { character in defining value map.
Whitespace is also key in delimiting the bodies of control structures in Python.
Specifically, a block of code is indented to designate it as the body of a control
structure, and nested control structures use increasing amounts of indentation. In
Code Fragment 1.1, the body of the while loop consists of the subsequent 8 lines,
including a nested conditional structure.
Comments are annotations provided for human readers, yet ignored by the
Python interpreter. The primary syntax for comments in Python is based on use
of the # character, which designates the remainder of the line as a comment.
print( Welcome to the GPA calculator. )
print( Please enter all your letter grades, one per line. )
print( Enter a blank line to designate the end. )
# map from letter grade to point value
points = { A+ :4.0, A :4.0, A- :3.67, B+ :3.33, B :3.0, B- :2.67,
C+ :2.33, C :2.0, C :1.67, D+ :1.33, D :1.0, F :0.0}
num courses = 0
total points = 0
done = False
while not done:
grade = input( ) # read line from user
if grade == : # empty line was entered
done = True
elif grade not in points: # unrecognized grade entered
print("Unknown grade {0} being ignored".format(grade))
else:
num courses += 1
total points += points[grade]
if num courses > 0: # avoid division by zero
print( Your GPA is {0:.3} .format(total points / num courses))
Code Fragment 1.1: A Python program that computes a grade-point average (GPA).

www.it-ebooks.info
4 Chapter 1. Python Primer

1.2 Objects in Python


Python is an object-oriented language and classes form the basis for all data types.
In this section, we describe key aspects of Python’s object model, and we intro-
duce Python’s built-in classes, such as the int class for integers, the float class
for floating-point values, and the str class for character strings. A more thorough
presentation of object-orientation is the focus of Chapter 2.

1.2.1 Identifiers, Objects, and the Assignment Statement


The most important of all Python commands is an assignment statement, such as
temperature = 98.6
This command establishes temperature as an identifier (also known as a name),
and then associates it with the object expressed on the right-hand side of the equal
sign, in this case a floating-point object with value 98.6. We portray the outcome
of this assignment in Figure 1.1.
float
temperature
98.6

Figure 1.1: The identifier temperature references an instance of the float class
having value 98.6.

Identifiers
Identifiers in Python are case-sensitive, so temperature and Temperature are dis-
tinct names. Identifiers can be composed of almost any combination of letters,
numerals, and underscore characters (or more general Unicode characters). The
primary restrictions are that an identifier cannot begin with a numeral (thus 9lives
is an illegal name), and that there are 33 specially reserved words that cannot be
used as identifiers, as shown in Table 1.1.

Reserved Words
False as continue else from in not return yield
None assert def except global is or try
True break del finally if lambda pass while
and class elif for import nonlocal raise with
Table 1.1: A listing of the reserved words in Python. These names cannot be used
as identifiers.

www.it-ebooks.info
1.2. Objects in Python 5
For readers familiar with other programming languages, the semantics of a
Python identifier is most similar to a reference variable in Java or a pointer variable
in C++. Each identifier is implicitly associated with the memory address of the
object to which it refers. A Python identifier may be assigned to a special object
named None, serving a similar purpose to a null reference in Java or C++.
Unlike Java and C++, Python is a dynamically typed language, as there is no
advance declaration associating an identifier with a particular data type. An iden-
tifier can be associated with any type of object, and it can later be reassigned to
another object of the same (or different) type. Although an identifier has no de-
clared type, the object to which it refers has a definite type. In our first example,
the characters 98.6 are recognized as a floating-point literal, and thus the identifier
temperature is associated with an instance of the float class having that value.
A programmer can establish an alias by assigning a second identifier to an
existing object. Continuing with our earlier example, Figure 1.2 portrays the result
of a subsequent assignment, original = temperature.

float
temperature original
98.6

Figure 1.2: Identifiers temperature and original are aliases for the same object.
Once an alias has been established, either name can be used to access the under-
lying object. If that object supports behaviors that affect its state, changes enacted
through one alias will be apparent when using the other alias (because they refer to
the same object). However, if one of the names is reassigned to a new value using
a subsequent assignment statement, that does not affect the aliased object, rather it
breaks the alias. Continuing with our concrete example, we consider the command:
temperature = temperature + 5.0
The execution of this command begins with the evaluation of the expression on the
right-hand side of the = operator. That expression, temperature + 5.0, is eval-
uated based on the existing binding of the name temperature, and so the result
has value 103.6, that is, 98.6 + 5.0. That result is stored as a new floating-point
instance, and only then is the name on the left-hand side of the assignment state-
ment, temperature, (re)assigned to the result. The subsequent configuration is dia-
grammed in Figure 1.3. Of particular note, this last command had no effect on the
value of the existing float instance that identifier original continues to reference.
float float
temperature original
103.6 98.6

Figure 1.3: The temperature identifier has been assigned to a new value, while
original continues to refer to the previously existing value.

www.it-ebooks.info
6 Chapter 1. Python Primer

1.2.2 Creating and Using Objects


Instantiation
The process of creating a new instance of a class is known as instantiation. In
general, the syntax for instantiating an object is to invoke the constructor of a class.
For example, if there were a class named Widget, we could create an instance of
that class using a syntax such as w = Widget( ), assuming that the constructor does
not require any parameters. If the constructor does require parameters, we might
use a syntax such as Widget(a, b, c) to construct a new instance.
Many of Python’s built-in classes (discussed in Section 1.2.3) support what is
known as a literal form for designating new instances. For example, the command
temperature = 98.6 results in the creation of a new instance of the float class; the
term 98.6 in that expression is a literal form. We discuss further cases of Python
literals in the coming section.
From a programmer’s perspective, yet another way to indirectly create a new
instance of a class is to call a function that creates and returns such an instance. For
example, Python has a built-in function named sorted (see Section 1.5.2) that takes
a sequence of comparable elements as a parameter and returns a new instance of
the list class containing those elements in sorted order.

Calling Methods
Python supports traditional functions (see Section 1.5) that are invoked with a syn-
tax such as sorted(data), in which case data is a parameter sent to the function.
Python’s classes may also define one or more methods (also known as member
functions), which are invoked on a specific instance of a class using the dot (“.”)
operator. For example, Python’s list class has a method named sort that can be
invoked with a syntax such as data.sort( ). This particular method rearranges the
contents of the list so that they are sorted.
The expression to the left of the dot identifies the object upon which the method
is invoked. Often, this will be an identifier (e.g., data), but we can use the dot op-
erator to invoke a method upon the immediate result of some other operation. For
example, if response identifies a string instance (we will discuss strings later in this
section), the syntax response.lower( ).startswith( y ) first evaluates the method
call, response.lower( ), which itself returns a new string instance, and then the
startswith( y ) method is called on that intermediate string.
When using a method of a class, it is important to understand its behavior.
Some methods return information about the state of an object, but do not change
that state. These are known as accessors. Other methods, such as the sort method
of the list class, do change the state of an object. These methods are known as
mutators or update methods.

www.it-ebooks.info
1.2. Objects in Python 7

1.2.3 Python’s Built-In Classes


Table 1.2 provides a summary of commonly used, built-in classes in Python; we
take particular note of which classes are mutable and which are immutable. A class
is immutable if each object of that class has a fixed value upon instantiation that
cannot subsequently be changed. For example, the float class is immutable. Once
an instance has been created, its value cannot be changed (although an identifier
referencing that object can be reassigned to a different value).

Class Description Immutable?


bool Boolean value 
int integer (arbitrary magnitude) 
float floating-point number 
list mutable sequence of objects
tuple immutable sequence of objects 
str character string 
set unordered set of distinct objects
frozenset immutable form of set class 
dict associative mapping (aka dictionary)
Table 1.2: Commonly used built-in classes for Python

In this section, we provide an introduction to these classes, discussing their


purpose and presenting several means for creating instances of the classes. Literal
forms (such as 98.6) exist for most of the built-in classes, and all of the classes
support a traditional constructor form that creates instances that are based upon
one or more existing values. Operators supported by these classes are described in
Section 1.3. More detailed information about these classes can be found in later
chapters as follows: lists and tuples (Chapter 5); strings (Chapters 5 and 13, and
Appendix A); sets and dictionaries (Chapter 10).

The bool Class


The bool class is used to manipulate logical (Boolean) values, and the only two
instances of that class are expressed as the literals True and False. The default
constructor, bool( ), returns False, but there is no reason to use that syntax rather
than the more direct literal form. Python allows the creation of a Boolean value
from a nonboolean type using the syntax bool(foo) for value foo. The interpretation
depends upon the type of the parameter. Numbers evaluate to False if zero, and
True if nonzero. Sequences and other container types, such as strings and lists,
evaluate to False if empty and True if nonempty. An important application of this
interpretation is the use of a nonboolean value as a condition in a control structure.

www.it-ebooks.info
8 Chapter 1. Python Primer
The int Class

The int and float classes are the primary numeric types in Python. The int class is
designed to represent integer values with arbitrary magnitude. Unlike Java and
C++, which support different integral types with different precisions (e.g., int,
short, long), Python automatically chooses the internal representation for an in-
teger based upon the magnitude of its value. Typical literals for integers include 0,
137, and −23. In some contexts, it is convenient to express an integral value using
binary, octal, or hexadecimal. That can be done by using a prefix of the number 0
and then a character to describe the base. Example of such literals are respectively
0b1011, 0o52, and 0x7f.
The integer constructor, int( ), returns value 0 by default. But this constructor
can be used to construct an integer value based upon an existing value of another
type. For example, if f represents a floating-point value, the syntax int(f) produces
the truncated value of f. For example, both int(3.14) and int(3.99) produce the
value 3, while int(−3.9) produces the value −3. The constructor can also be used
to parse a string that is presumed to represent an integral value (such as one en-
tered by a user). If s represents a string, then int(s) produces the integral value
that string represents. For example, the expression int( 137 ) produces the inte-
ger value 137. If an invalid string is given as a parameter, as in int( hello ), a
ValueError is raised (see Section 1.7 for discussion of Python’s exceptions). By de-
fault, the string must use base 10. If conversion from a different base is desired, that
base can be indicated as a second, optional, parameter. For example, the expression
int( 7f , 16) evaluates to the integer 127.

The float Class

The float class is the sole floating-point type in Python, using a fixed-precision
representation. Its precision is more akin to a double in Java or C++, rather than
those languages’ float type. We have already discussed a typical literal form, 98.6.
We note that the floating-point equivalent of an integral number can be expressed
directly as 2.0. Technically, the trailing zero is optional, so some programmers
might use the expression 2. to designate this floating-point literal. One other form
of literal for floating-point values uses scientific notation. For example, the literal
6.022e23 represents the mathematical value 6.022 × 1023 .
The constructor form of float( ) returns 0.0. When given a parameter, the con-
structor attempts to return the equivalent floating-point value. For example, the call
float(2) returns the floating-point value 2.0. If the parameter to the constructor is
a string, as with float( 3.14 ), it attempts to parse that string as a floating-point
value, raising a ValueError as an exception.

www.it-ebooks.info
1.2. Objects in Python 9
Sequence Types: The list, tuple, and str Classes
The list, tuple, and str classes are sequence types in Python, representing a col-
lection of values in which the order is significant. The list class is the most general,
representing a sequence of arbitrary objects (akin to an “array” in other languages).
The tuple class is an immutable version of the list class, benefiting from a stream-
lined internal representation. The str class is specially designed for representing
an immutable sequence of text characters. We note that Python does not have a
separate class for characters; they are just strings with length one.

The list Class


A list instance stores a sequence of objects. A list is a referential structure, as it
technically stores a sequence of references to its elements (see Figure 1.4). El-
ements of a list may be arbitrary objects (including the None object). Lists are
array-based sequences and are zero-indexed, thus a list of length n has elements
indexed from 0 to n − 1 inclusive. Lists are perhaps the most used container type in
Python and they will be extremely central to our study of data structures and algo-
rithms. They have many valuable behaviors, including the ability to dynamically
expand and contract their capacities as needed. In this chapter, we will discuss only
the most basic properties of lists. We revisit the inner working of all of Python’s
sequence types as the focus of Chapter 5.
Python uses the characters [ ] as delimiters for a list literal, with [ ] itself being
an empty list. As another example, [ red , green , blue ] is a list containing
three string instances. The contents of a list literal need not be expressed as literals;
if identifiers a and b have been established, then syntax [a, b] is legitimate.
The list( ) constructor produces an empty list by default. However, the construc-
tor will accept any parameter that is of an iterable type. We will discuss iteration
further in Section 1.8, but examples of iterable types include all of the standard con-
tainer types (e.g., strings, list, tuples, sets, dictionaries). For example, the syntax
list( hello ) produces a list of individual characters, [ h , e , l , l , o ].
Because an existing list is itself iterable, the syntax backup = list(data) can be
used to construct a new list instance referencing the same contents as the original.

2 3 5 7 11 13 17 19 23 29 31

primes:
0 1 2 3 4 5 6 7 8 9 10

Figure 1.4: Python’s internal representation of a list of integers, instantiated as


prime = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31]. The implicit indices of the ele-
ments are shown below each entry.

www.it-ebooks.info
10 Chapter 1. Python Primer
The tuple Class
The tuple class provides an immutable version of a sequence, and therefore its
instances have an internal representation that may be more streamlined than that of
a list. While Python uses the [ ] characters to delimit a list, parentheses delimit a
tuple, with ( ) being an empty tuple. There is one important subtlety. To express
a tuple of length one as a literal, a comma must be placed after the element, but
within the parentheses. For example, (17,) is a one-element tuple. The reason for
this requirement is that, without the trailing comma, the expression (17) is viewed
as a simple parenthesized numeric expression.

The str Class


Python’s str class is specifically designed to efficiently represent an immutable
sequence of characters, based upon the Unicode international character set. Strings
have a more compact internal representation than the referential lists and tuples, as
portrayed in Figure 1.5.

S A M P L E
0 1 2 3 4 5

Figure 1.5: A Python string, which is an indexed sequence of characters.

String literals can be enclosed in single quotes, as in hello , or double


quotes, as in "hello". This choice is convenient, especially when using an-
other of the quotation characters as an actual character in the sequence, as in
"Don t worry". Alternatively, the quote delimiter can be designated using a
backslash as a so-called escape character, as in Don\ t worry . Because the
backslash has this purpose, the backslash must itself be escaped to occur as a natu-
ral character of the string literal, as in C:\\Python\\ , for a string that would be
displayed as C:\Python\. Other commonly escaped characters are \n for newline
and \t for tab. Unicode characters can be included, such as 20\u20AC for the
string 20 .
Python also supports using the delimiter or """ to begin and end a string
literal. The advantage of such triple-quoted strings is that newline characters can
be embedded naturally (rather than escaped as \n). This can greatly improve the
readability of long, multiline strings in source code. For example, at the beginning
of Code Fragment 1.1, rather than use separate print statements for each line of
introductory output, we can use a single print statement, as follows:
print(”””Welcome to the GPA calculator.
Please enter all your letter grades, one per line.
Enter a blank line to designate the end.”””)

www.it-ebooks.info
1.2. Objects in Python 11
The set and frozenset Classes

Python’s set class represents the mathematical notion of a set, namely a collection
of elements, without duplicates, and without an inherent order to those elements.
The major advantage of using a set, as opposed to a list, is that it has a highly
optimized method for checking whether a specific element is contained in the set.
This is based on a data structure known as a hash table (which will be the primary
topic of Chapter 10). However, there are two important restrictions due to the
algorithmic underpinnings. The first is that the set does not maintain the elements
in any particular order. The second is that only instances of immutable types can be
added to a Python set. Therefore, objects such as integers, floating-point numbers,
and character strings are eligible to be elements of a set. It is possible to maintain a
set of tuples, but not a set of lists or a set of sets, as lists and sets are mutable. The
frozenset class is an immutable form of the set type, so it is legal to have a set of
frozensets.
Python uses curly braces { and } as delimiters for a set, for example, as {17}
or { red , green , blue }. The exception to this rule is that { } does not
represent an empty set; for historical reasons, it represents an empty dictionary
(see next paragraph). Instead, the constructor syntax set( ) produces an empty set.
If an iterable parameter is sent to the constructor, then the set of distinct elements
is produced. For example, set( hello ) produces { h , e , l , o }.

The dict Class

Python’s dict class represents a dictionary, or mapping, from a set of distinct keys
to associated values. For example, a dictionary might map from unique student ID
numbers, to larger student records (such as the student’s name, address, and course
grades). Python implements a dict using an almost identical approach to that of a
set, but with storage of the associated values.
A dictionary literal also uses curly braces, and because dictionaries were intro-
duced in Python prior to sets, the literal form { } produces an empty dictionary.
A nonempty dictionary is expressed using a comma-separated series of key:value
pairs. For example, the dictionary { ga : Irish , de : German } maps
ga to Irish and de to German .
The constructor for the dict class accepts an existing mapping as a parameter,
in which case it creates a new dictionary with identical associations as the existing
one. Alternatively, the constructor accepts a sequence of key-value pairs as a pa-
rameter, as in dict(pairs) with pairs = [( ga , Irish ), ( de , German )].

www.it-ebooks.info
12 Chapter 1. Python Primer

1.3 Expressions, Operators, and Precedence


In the previous section, we demonstrated how names can be used to identify ex-
isting objects, and how literals and constructors can be used to create instances of
built-in classes. Existing values can be combined into larger syntactic expressions
using a variety of special symbols and keywords known as operators. The seman-
tics of an operator depends upon the type of its operands. For example, when a
and b are numbers, the syntax a + b indicates addition, while if a and b are strings,
the operator indicates concatenation. In this section, we describe Python’s opera-
tors in various contexts of the built-in types.
We continue, in Section 1.3.1, by discussing compound expressions, such as
a + b c, which rely on the evaluation of two or more operations. The order
in which the operations of a compound expression are evaluated can affect the
overall value of the expression. For this reason, Python defines a specific order of
precedence for evaluating operators, and it allows a programmer to override this
order by using explicit parentheses to group subexpressions.

Logical Operators
Python supports the following keyword operators for Boolean values:
not unary negation
and conditional and
or conditional or
The and and or operators short-circuit, in that they do not evaluate the second
operand if the result can be determined based on the value of the first operand.
This feature is useful when constructing Boolean expressions in which we first test
that a certain condition holds (such as a reference not being None), and then test a
condition that could have otherwise generated an error condition had the prior test
not succeeded.

Equality Operators
Python supports the following operators to test two notions of equality:
is same identity
is not different identity
== equivalent
!= not equivalent
The expression a is b evaluates to True, precisely when identifiers a and b are
aliases for the same object. The expression a == b tests a more general notion of
equivalence. If identifiers a and b refer to the same object, then a == b should also
evaluate to True. Yet a == b also evaluates to True when the identifiers refer to

www.it-ebooks.info
1.3. Expressions, Operators, and Precedence 13
different objects that happen to have values that are deemed equivalent. The precise
notion of equivalence depends on the data type. For example, two strings are con-
sidered equivalent if they match character for character. Two sets are equivalent if
they have the same contents, irrespective of order. In most programming situations,
the equivalence tests == and != are the appropriate operators; use of is and is not
should be reserved for situations in which it is necessary to detect true aliasing.

Comparison Operators
Data types may define a natural order via the following operators:
< less than
<= less than or equal to
> greater than
>= greater than or equal to
These operators have expected behavior for numeric types, and are defined lexi-
cographically, and case-sensitively, for strings. An exception is raised if operands
have incomparable types, as with 5 < hello .

Arithmetic Operators
Python supports the following arithmetic operators:
+ addition
− subtraction
multiplication
/ true division
// integer division
% the modulo operator
The use of addition, subtraction, and multiplication is straightforward, noting that if
both operands have type int, then the result is an int as well; if one or both operands
have type float, the result will be a float.
Python takes more care in its treatment of division. We first consider the case
in which both operands have type int, for example, the quantity 27 divided by
4. In mathematical notation, 27 ÷ 4 = 6 34 = 6.75. In Python, the / operator
designates true division, returning the floating-point result of the computation.
Thus, 27 / 4 results in the float value 6.75. Python supports the pair of opera-
tors // and % to perform the integral calculations, with expression 27 // 4 evalu-
ating to int value 6 (the mathematical floor of the quotient), and expression 27 % 4
evaluating to int value 3, the remainder of the integer division. We note that lan-
guages such as C, C++, and Java do not support the // operator; instead, the / op-
erator returns the truncated quotient when both operands have integral type, and the
result of true division when at least one operand has a floating-point type.

www.it-ebooks.info
14 Chapter 1. Python Primer
Python carefully extends the semantics of // and % to cases where one or both
operands are negative. For the sake of notation, let us assume that variables n
and m represent respectively the dividend and divisor of a quotient m n , and that
q = n // m and r = n % m. Python guarantees that q m + r will equal n. We
already saw an example of this identity with positive operands, as 6 ∗ 4 + 3 = 27.
When the divisor m is positive, Python further guarantees that 0 ≤ r < m. As
a consequence, we find that −27 // 4 evaluates to −7 and −27 % 4 evaluates
to 1, as (−7) ∗ 4 + 1 = −27. When the divisor is negative, Python guarantees that
m < r ≤ 0. As an example, 27 // −4 is −7 and 27 % −4 is −1, satisfying the
identity 27 = (−7) ∗ (−4) + (−1).
The conventions for the // and % operators are even extended to floating-
point operands, with the expression q = n // m being the integral floor of the
quotient, and r = n % m being the “remainder” to ensure that q m + r equals
n. For example, 8.2 // 3.14 evaluates to 2.0 and 8.2 % 3.14 evaluates to 1.92, as
2.0 ∗ 3.14 + 1.92 = 8.2.

Bitwise Operators
Python provides the following bitwise operators for integers:
∼ bitwise complement (prefix unary operator)
& bitwise and
| bitwise or
ˆ bitwise exclusive-or
<< shift bits left, filling in with zeros
>> shift bits right, filling in with sign bit

Sequence Operators
Each of Python’s built-in sequence types (str, tuple, and list) support the following
operator syntaxes:
s[j] element at index j
s[start:stop] slice including indices [start,stop)
s[start:stop:step] slice including indices start, start + step,
start + 2 step, . . . , up to but not equalling or stop
s+t concatenation of sequences
k s shorthand for s + s + s + ... (k times)
val in s containment check
val not in s non-containment check
Python relies on zero-indexing of sequences, thus a sequence of length n has ele-
ments indexed from 0 to n − 1 inclusive. Python also supports the use of negative
indices, which denote a distance from the end of the sequence; index −1 denotes
the last element, index −2 the second to last, and so on. Python uses a slicing

www.it-ebooks.info
1.3. Expressions, Operators, and Precedence 15
notation to describe subsequences of a sequence. Slices are described as half-open
intervals, with a start index that is included, and a stop index that is excluded. For
example, the syntax data[3:8] denotes a subsequence including the five indices:
3, 4, 5, 6, 7. An optional “step” value, possibly negative, can be indicated as a third
parameter of the slice. If a start index or stop index is omitted in the slicing nota-
tion, it is presumed to designate the respective extreme of the original sequence.
Because lists are mutable, the syntax s[j] = val can be used to replace an ele-
ment at a given index. Lists also support a syntax, del s[j], that removes the desig-
nated element from the list. Slice notation can also be used to replace or delete a
sublist.
The notation val in s can be used for any of the sequences to see if there is an
element equivalent to val in the sequence. For strings, this syntax can be used to
check for a single character or for a larger substring, as with amp in example .
All sequences define comparison operations based on lexicographic order, per-
forming an element by element comparison until the first difference is found. For
example, [5, 6, 9] < [5, 7] because of the entries at index 1. Therefore, the follow-
ing operations are supported by sequence types:
s == t equivalent (element by element)
s != t not equivalent
s < t lexicographically less than
s <= t lexicographically less than or equal to
s > t lexicographically greater than
s >= t lexicographically greater than or equal to

Operators for Sets and Dictionaries


Sets and frozensets support the following operators:
key in s containment check
key not in s non-containment check
s1 == s2 s1 is equivalent to s2
s1 != s2 s1 is not equivalent to s2
s1 <= s2 s1 is subset of s2
s1 < s2 s1 is proper subset of s2
s1 >= s2 s1 is superset of s2
s1 > s2 s1 is proper superset of s2
s1 | s2 the union of s1 and s2
s1 & s2 the intersection of s1 and s2
s1 − s2 the set of elements in s1 but not s2
s1 ˆ s2 the set of elements in precisely one of s1 or s2
Note well that sets do not guarantee a particular order of their elements, so the
comparison operators, such as <, are not lexicographic; rather, they are based on
the mathematical notion of a subset. As a result, the comparison operators define

www.it-ebooks.info
16 Chapter 1. Python Primer
a partial order, but not a total order, as disjoint sets are neither “less than,” “equal
to,” or “greater than” each other. Sets also support many fundamental behaviors
through named methods (e.g., add, remove); we will explore their functionality
more fully in Chapter 10.
Dictionaries, like sets, do not maintain a well-defined order on their elements.
Furthermore, the concept of a subset is not typically meaningful for dictionaries, so
the dict class does not support operators such as <. Dictionaries support the notion
of equivalence, with d1 == d2 if the two dictionaries contain the same set of key-
value pairs. The most widely used behavior of dictionaries is accessing a value
associated with a particular key k with the indexing syntax, d[k]. The supported
operators are as follows:

d[key] value associated with given key


d[key] = value set (or reset) the value associated with given key
del d[key] remove key and its associated value from dictionary
key in d containment check
key not in d non-containment check
d1 == d2 d1 is equivalent to d2
d1 != d2 d1 is not equivalent to d2

Dictionaries also support many useful behaviors through named methods, which
we explore more fully in Chapter 10.

Extended Assignment Operators

Python supports an extended assignment operator for most binary operators, for
example, allowing a syntax such as count += 5. By default, this is a shorthand for
the more verbose count = count + 5. For an immutable type, such as a number or
a string, one should not presume that this syntax changes the value of the existing
object, but instead that it will reassign the identifier to a newly constructed value.
(See discussion of Figure 1.3.) However, it is possible for a type to redefine such
semantics to mutate the object, as the list class does for the += operator.
alpha = [1, 2, 3]
beta = alpha # an alias for alpha
beta += [4, 5] # extends the original list with two more elements
beta = beta + [6, 7] # reassigns beta to a new list [1, 2, 3, 4, 5, 6, 7]
print(alpha) # will be [1, 2, 3, 4, 5]
This example demonstrates the subtle difference between the list semantics for the
syntax beta += foo versus beta = beta + foo.

www.it-ebooks.info
1.3. Expressions, Operators, and Precedence 17

1.3.1 Compound Expressions and Operator Precedence


Programming languages must have clear rules for the order in which compound
expressions, such as 5 + 2 3, are evaluated. The formal order of precedence
for operators in Python is given in Table 1.3. Operators in a category with higher
precedence will be evaluated before those with lower precedence, unless the expres-
sion is otherwise parenthesized. Therefore, we see that Python gives precedence to
multiplication over addition, and therefore evaluates the expression 5 + 2 3 as
5 + (2 3), with value 11, but the parenthesized expression (5 + 2) 3 evalu-
ates to value 21. Operators within a category are typically evaluated from left to
right, thus 5 − 2 + 3 has value 6. Exceptions to this rule include that unary oper-
ators and exponentiation are evaluated from right to left.
Python allows a chained assignment, such as x = y = 0, to assign multiple
identifiers to the rightmost value. Python also allows the chaining of comparison
operators. For example, the expression 1 <= x + y <= 10 is evaluated as the
compound (1 <= x + y) and (x + y <= 10), but without computing the inter-
mediate value x + y twice.

Operator Precedence
Type Symbols
1 member access expr.member
function/method calls expr(...)
2
container subscripts/slices expr[...]
3 exponentiation
4 unary operators +expr, −expr, ˜expr
5 multiplication, division , /, //, %
6 addition, subtraction +, −
7 bitwise shifting <<, >>
8 bitwise-and &
9 bitwise-xor ˆ
10 bitwise-or |
comparisons is, is not, ==, !=, <, <=, >, >=
11
containment in, not in
12 logical-not not expr
13 logical-and and
14 logical-or or
15 conditional val1 if cond else val2
16 assignments =, +=, −=, =, etc.

Table 1.3: Operator precedence in Python, with categories ordered from highest
precedence to lowest precedence. When stated, we use expr to denote a literal,
identifier, or result of a previously evaluated expression. All operators without
explicit mention of expr are binary operators, with syntax expr1 operator expr2.

www.it-ebooks.info
18 Chapter 1. Python Primer

1.4 Control Flow


In this section, we review Python’s most fundamental control structures: condi-
tional statements and loops. Common to all control structures is the syntax used
in Python for defining blocks of code. The colon character is used to delimit the
beginning of a block of code that acts as a body for a control structure. If the body
can be stated as a single executable statement, it can technically placed on the same
line, to the right of the colon. However, a body is more typically typeset as an
indented block starting on the line following the colon. Python relies on the inden-
tation level to designate the extent of that block of code, or any nested blocks of
code within. The same principles will be applied when designating the body of a
function (see Section 1.5), and the body of a class (see Section 2.3).

1.4.1 Conditionals
Conditional constructs (also known as if statements) provide a way to execute a
chosen block of code based on the run-time evaluation of one or more Boolean
expressions. In Python, the most general form of a conditional is written as follows:
if first condition:
first body
elif second condition:
second body
elif third condition:
third body
else:
fourth body
Each condition is a Boolean expression, and each body contains one or more com-
mands that are to be executed conditionally. If the first condition succeeds, the first
body will be executed; no other conditions or bodies are evaluated in that case.
If the first condition fails, then the process continues in similar manner with the
evaluation of the second condition. The execution of this overall construct will
cause precisely one of the bodies to be executed. There may be any number of
elif clauses (including zero), and the final else clause is optional. As described on
page 7, nonboolean types may be evaluated as Booleans with intuitive meanings.
For example, if response is a string that was entered by a user, and we want to
condition a behavior on this being a nonempty string, we may write
if response:
as a shorthand for the equivalent,
if response != :

www.it-ebooks.info
1.4. Control Flow 19
As a simple example, a robot controller might have the following logic:
if door is closed:
open door( )
advance( )
Notice that the final command, advance( ), is not indented and therefore not part of
the conditional body. It will be executed unconditionally (although after opening a
closed door).
We may nest one control structure within another, relying on indentation to
make clear the extent of the various bodies. Revisiting our robot example, here is a
more complex control that accounts for unlocking a closed door.
if door is closed:
if door is locked:
unlock door( )
open door( )
advance( )
The logic expressed by this example can be diagrammed as a traditional flowchart,
as portrayed in Figure 1.6.

False True
door is closed

False True
door is locked

unlock door( )

open door( )

advance( )

Figure 1.6: A flowchart describing the logic of nested conditional statements.

www.it-ebooks.info
20 Chapter 1. Python Primer

1.4.2 Loops
Python offers two distinct looping constructs. A while loop allows general repeti-
tion based upon the repeated testing of a Boolean condition. A for loop provides
convenient iteration of values from a defined series (such as characters of a string,
elements of a list, or numbers within a given range). We discuss both forms in this
section.

While Loops
The syntax for a while loop in Python is as follows:
while condition:
body
As with an if statement, condition can be an arbitrary Boolean expression, and
body can be an arbitrary block of code (including nested control structures). The
execution of a while loop begins with a test of the Boolean condition. If that condi-
tion evaluates to True, the body of the loop is performed. After each execution of
the body, the loop condition is retested, and if it evaluates to True, another iteration
of the body is performed. When the conditional test evaluates to False (assuming
it ever does), the loop is exited and the flow of control continues just beyond the
body of the loop.
As an example, here is a loop that advances an index through a sequence of
characters until finding an entry with value X or reaching the end of the sequence.
j=0
while j < len(data) and data[j] != X :
j += 1
The len function, which we will introduce in Section 1.5.2, returns the length of a
sequence such as a list or string. The correctness of this loop relies on the short-
circuiting behavior of the and operator, as described on page 12. We intention-
ally test j < len(data) to ensure that j is a valid index, prior to accessing element
data[j]. Had we written that compound condition with the opposite order, the eval-
uation of data[j] would eventually raise an IndexError when X is not found. (See
Section 1.7 for discussion of exceptions.)
As written, when this loop terminates, variable j’s value will be the index of
the leftmost occurrence of X , if found, or otherwise the length of the sequence
(which is recognizable as an invalid index to indicate failure of the search). It is
worth noting that this code behaves correctly, even in the special case when the list
is empty, as the condition j < len(data) will initially fail and the body of the loop
will never be executed.

www.it-ebooks.info
1.4. Control Flow 21
For Loops

Python’s for-loop syntax is a more convenient alternative to a while loop when


iterating through a series of elements. The for-loop syntax can be used on any
type of iterable structure, such as a list, tuple str, set, dict, or file (we will discuss
iterators more formally in Section 1.8). Its general syntax appears as follows.
for element in iterable:
body # body may refer to element as an identifier

For readers familiar with Java, the semantics of Python’s for loop is similar to the
“for each” loop style introduced in Java 1.5.
As an instructive example of such a loop, we consider the task of computing
the sum of a list of numbers. (Admittedly, Python has a built-in function, sum, for
this purpose.) We perform the calculation with a for loop as follows, assuming that
data identifies the list:
total = 0
for val in data:
total += val # note use of the loop variable, val

The loop body executes once for each element of the data sequence, with the iden-
tifier, val, from the for-loop syntax assigned at the beginning of each pass to a
respective element. It is worth noting that val is treated as a standard identifier. If
the element of the original data happens to be mutable, the val identifier can be
used to invoke its methods. But a reassignment of identifier val to a new value has
no affect on the original data, nor on the next iteration of the loop.
As a second classic example, we consider the task of finding the maximum
value in a list of elements (again, admitting that Python’s built-in max function
already provides this support). If we can assume that the list, data, has at least one
element, we could implement this task as follows:
biggest = data[0] # as we assume nonempty list
for val in data:
if val > biggest:
biggest = val

Although we could accomplish both of the above tasks with a while loop, the
for-loop syntax had an advantage of simplicity, as there is no need to manage an
explicit index into the list nor to author a Boolean loop condition. Furthermore, we
can use a for loop in cases for which a while loop does not apply, such as when
iterating through a collection, such as a set, that does not support any direct form
of indexing.

www.it-ebooks.info
22 Chapter 1. Python Primer
Index-Based For Loops
The simplicity of a standard for loop over the elements of a list is wonderful; how-
ever, one limitation of that form is that we do not know where an element resides
within the sequence. In some applications, we need knowledge of the index of an
element within the sequence. For example, suppose that we want to know where
the maximum element in a list resides.
Rather than directly looping over the elements of the list in that case, we prefer
to loop over all possible indices of the list. For this purpose, Python provides
a built-in class named range that generates integer sequences. (We will discuss
generators in Section 1.8.) In simplest form, the syntax range(n) generates the
series of n values from 0 to n − 1. Conveniently, these are precisely the series of
valid indices into a sequence of length n. Therefore, a standard Python idiom for
looping through the series of indices of a data sequence uses a syntax,
for j in range(len(data)):
In this case, identifier j is not an element of the data—it is an integer. But the
expression data[j] can be used to retrieve the respective element. For example, we
can find the index of the maximum element of a list as follows:
big index = 0
for j in range(len(data)):
if data[j] > data[big index]:
big index = j

Break and Continue Statements


Python supports a break statement that immediately terminate a while or for loop
when executed within its body. More formally, if applied within nested control
structures, it causes the termination of the most immediately enclosing loop. As
a typical example, here is code that determines whether a target value occurs in a
data set:
found = False
for item in data:
if item == target:
found = True
break
Python also supports a continue statement that causes the current iteration of a
loop body to stop, but with subsequent passes of the loop proceeding as expected.
We recommend that the break and continue statements be used sparingly. Yet,
there are situations in which these commands can be effectively used to avoid in-
troducing overly complex logical conditions.

www.it-ebooks.info
1.5. Functions 23

1.5 Functions
In this section, we explore the creation of and use of functions in Python. As we
did in Section 1.2.2, we draw a distinction between functions and methods. We
use the general term function to describe a traditional, stateless function that is in-
voked without the context of a particular class or an instance of that class, such as
sorted(data). We use the more specific term method to describe a member function
that is invoked upon a specific object using an object-oriented message passing syn-
tax, such as data.sort( ). In this section, we only consider pure functions; methods
will be explored with more general object-oriented principles in Chapter 2.
We begin with an example to demonstrate the syntax for defining functions in
Python. The following function counts the number of occurrences of a given target
value within any form of iterable data set.
def count(data, target):
n=0
for item in data:
if item == target: # found a match
n += 1
return n
The first line, beginning with the keyword def, serves as the function’s signature.
This establishes a new identifier as the name of the function (count, in this exam-
ple), and it establishes the number of parameters that it expects, as well as names
identifying those parameters (data and target, in this example). Unlike Java and
C++, Python is a dynamically typed language, and therefore a Python signature
does not designate the types of those parameters, nor the type (if any) of a return
value. Those expectations should be stated in the function’s documentation (see
Section 2.2.3) and can be enforced within the body of the function, but misuse of a
function will only be detected at run-time.
The remainder of the function definition is known as the body of the func-
tion. As is the case with control structures in Python, the body of a function is
typically expressed as an indented block of code. Each time a function is called,
Python creates a dedicated activation record that stores information relevant to the
current call. This activation record includes what is known as a namespace (see
Section 1.10) to manage all identifiers that have local scope within the current call.
The namespace includes the function’s parameters and any other identifiers that are
defined locally within the body of the function. An identifier in the local scope
of the function caller has no relation to any identifier with the same name in the
caller’s scope (although identifiers in different scopes may be aliases to the same
object). In our first example, the identifier n has scope that is local to the function
call, as does the identifier item, which is established as the loop variable.

www.it-ebooks.info
24 Chapter 1. Python Primer
Return Statement
A return statement is used within the body of a function to indicate that the func-
tion should immediately cease execution, and that an expressed value should be
returned to the caller. If a return statement is executed without an explicit argu-
ment, the None value is automatically returned. Likewise, None will be returned if
the flow of control ever reaches the end of a function body without having executed
a return statement. Often, a return statement will be the final command within the
body of the function, as was the case in our earlier example of a count function.
However, there can be multiple return statements in the same function, with con-
ditional logic controlling which such command is executed, if any. As a further
example, consider the following function that tests if a value exists in a sequence.
def contains(data, target):
for item in target:
if item == target: # found a match
return True
return False
If the conditional within the loop body is ever satisfied, the return True statement is
executed and the function immediately ends, with True designating that the target
value was found. Conversely, if the for loop reaches its conclusion without ever
finding the match, the final return False statement will be executed.

1.5.1 Information Passing


To be a successful programmer, one must have clear understanding of the mech-
anism in which a programming language passes information to and from a func-
tion. In the context of a function signature, the identifiers used to describe the
expected parameters are known as formal parameters, and the objects sent by the
caller when invoking the function are the actual parameters. Parameter passing
in Python follows the semantics of the standard assignment statement. When a
function is invoked, each identifier that serves as a formal parameter is assigned, in
the function’s local scope, to the respective actual parameter that is provided by the
caller of the function.
For example, consider the following call to our count function from page 23:
prizes = count(grades, A )
Just before the function body is executed, the actual parameters, grades and A ,
are implicitly assigned to the formal parameters, data and target, as follows:
data = grades
target = A

www.it-ebooks.info
1.5. Functions 25
These assignment statements establish identifier data as an alias for grades and
target as a name for the string literal A . (See Figure 1.7.)
grades data target

list str
... A

Figure 1.7: A portrayal of parameter passing in Python, for the function call
count(grades, A ). Identifiers data and target are formal parameters defined
within the local scope of the count function.

The communication of a return value from the function back to the caller is
similarly implemented as an assignment. Therefore, with our sample invocation of
prizes = count(grades, A ), the identifier prizes in the caller’s scope is assigned
to the object that is identified as n in the return statement within our function body.
An advantage to Python’s mechanism for passing information to and from a
function is that objects are not copied. This ensures that the invocation of a function
is efficient, even in a case where a parameter or return value is a complex object.

Mutable Parameters
Python’s parameter passing model has additional implications when a parameter is
a mutable object. Because the formal parameter is an alias for the actual parameter,
the body of the function may interact with the object in ways that change its state.
Considering again our sample invocation of the count function, if the body of the
function executes the command data.append( F ), the new entry is added to the
end of the list identified as data within the function, which is one and the same as
the list known to the caller as grades. As an aside, we note that reassigning a new
value to a formal parameter with a function body, such as by setting data = [ ],
does not alter the actual parameter; such a reassignment simply breaks the alias.
Our hypothetical example of a count method that appends a new element to a
list lacks common sense. There is no reason to expect such a behavior, and it would
be quite a poor design to have such an unexpected effect on the parameter. There
are, however, many legitimate cases in which a function may be designed (and
clearly documented) to modify the state of a parameter. As a concrete example,
we present the following implementation of a method named scale that’s primary
purpose is to multiply all entries of a numeric data set by a given factor.
def scale(data, factor):
for j in range(len(data)):
data[j] = factor

www.it-ebooks.info
26 Chapter 1. Python Primer
Default Parameter Values

Python provides means for functions to support more than one possible calling
signature. Such a function is said to be polymorphic (which is Greek for “many
forms”). Most notably, functions can declare one or more default values for pa-
rameters, thereby allowing the caller to invoke a function with varying numbers of
actual parameters. As an artificial example, if a function is declared with signature
def foo(a, b=15, c=27):
there are three parameters, the last two of which offer default values. A caller is
welcome to send three actual parameters, as in foo(4, 12, 8), in which case the de-
fault values are not used. If, on the other hand, the caller only sends one parameter,
foo(4), the function will execute with parameters values a=4, b=15, c=27. If a
caller sends two parameters, they are assumed to be the first two, with the third be-
ing the default. Thus, foo(8, 20) executes with a=8, b=20, c=27. However, it is
illegal to define a function with a signature such as bar(a, b=15, c) with b having
a default value, yet not the subsequent c; if a default parameter value is present for
one parameter, it must be present for all further parameters.
As a more motivating example for the use of a default parameter, we revisit
the task of computing a student’s GPA (see Code Fragment 1.1). Rather than as-
sume direct input and output with the console, we prefer to design a function that
computes and returns a GPA. Our original implementation uses a fixed mapping
from each letter grade (such as a B−) to a corresponding point value (such as
2.67). While that point system is somewhat common, it may not agree with the
system used by all schools. (For example, some may assign an A+ grade a value
higher than 4.0.) Therefore, we design a compute gpa function, given in Code
Fragment 1.2, which allows the caller to specify a custom mapping from grades to
values, while offering the standard point system as a default.

def compute gpa(grades, points={ A+ :4.0, A :4.0, A- :3.67, B+ :3.33,


B :3.0, B- :2.67, C+ :2.33, C :2.0,
C :1.67, D+ :1.33, D :1.0, F :0.0}):
num courses = 0
total points = 0
for g in grades:
if g in points: # a recognizable grade
num courses += 1
total points += points[g]
return total points / num courses
Code Fragment 1.2: A function that computes a student’s GPA with a point value
system that can be customized as an optional parameter.

www.it-ebooks.info
1.5. Functions 27
As an additional example of an interesting polymorphic function, we consider
Python’s support for range. (Technically, this is a constructor for the range class,
but for the sake of this discussion, we can treat it as a pure function.) Three calling
syntaxes are supported. The one-parameter form, range(n), generates a sequence of
integers from 0 up to but not including n. A two-parameter form, range(start,stop)
generates integers from start up to, but not including, stop. A three-parameter
form, range(start, stop, step), generates a similar range as range(start, stop), but
with increments of size step rather than 1.
This combination of forms seems to violate the rules for default parameters.
In particular, when a single parameter is sent, as in range(n), it serves as the stop
value (which is the second parameter); the value of start is effectively 0 in that
case. However, this effect can be achieved with some sleight of hand, as follows:
def range(start, stop=None, step=1):
if stop is None:
stop = start
start = 0
...
From a technical perspective, when range(n) is invoked, the actual parameter n will
be assigned to formal parameter start. Within the body, if only one parameter is
received, the start and stop values are reassigned to provide the desired semantics.

Keyword Parameters
The traditional mechanism for matching the actual parameters sent by a caller, to
the formal parameters declared by the function signature is based on the concept
of positional arguments. For example, with signature foo(a=10, b=20, c=30),
parameters sent by the caller are matched, in the given order, to the formal param-
eters. An invocation of foo(5) indicates that a=5, while b and c are assigned their
default values.
Python supports an alternate mechanism for sending a parameter to a function
known as a keyword argument. A keyword argument is specified by explicitly
assigning an actual parameter to a formal parameter by name. For example, with
the above definition of function foo, a call foo(c=5) will invoke the function with
parameters a=10, b=20, c=5.
A function’s author can require that certain parameters be sent only through the
keyword-argument syntax. We never place such a restriction in our own function
definitions, but we will see several important uses of keyword-only parameters in
Python’s standard libraries. As an example, the built-in max function accepts a
keyword parameter, coincidentally named key, that can be used to vary the notion
of “maximum” that is used.

www.it-ebooks.info
28 Chapter 1. Python Primer
By default, max operates based upon the natural order of elements according
to the < operator for that type. But the maximum can be computed by comparing
some other aspect of the elements. This is done by providing an auxiliary function
that converts a natural element to some other value for the sake of comparison.
For example, if we are interested in finding a numeric value with magnitude that is
maximal (i.e., considering −35 to be larger than +20), we can use the calling syn-
tax max(a, b, key=abs). In this case, the built-in abs function is itself sent as the
value associated with the keyword parameter key. (Functions are first-class objects
in Python; see Section 1.10.) When max is called in this way, it will compare abs(a)
to abs(b), rather than a to b. The motivation for the keyword syntax as an alternate
to positional arguments is important in the case of max. This function is polymor-
phic in the number of arguments, allowing a call such as max(a,b,c,d); therefore,
it is not possible to designate a key function as a traditional positional element.
Sorting functions in Python also support a similar key parameter for indicating a
nonstandard order. (We explore this further in Section 9.4 and in Section 12.6.1,
when discussing sorting algorithms).

1.5.2 Python’s Built-In Functions


Table 1.4 provides an overview of common functions that are automatically avail-
able in Python, including the previously discussed abs, max, and range. When
choosing names for the parameters, we use identifiers x, y, z for arbitrary numeric
types, k for an integer, and a, b, and c for arbitrary comparable types. We use
the identifier, iterable, to represent an instance of any iterable type (e.g., str, list,
tuple, set, dict); we will discuss iterators and iterable data types in Section 1.8.
A sequence represents a more narrow category of indexable classes, including str,
list, and tuple, but neither set nor dict. Most of the entries in Table 1.4 can be
categorized according to their functionality as follows:
Input/Output: print, input, and open will be more fully explained in Section 1.6.
Character Encoding: ord and chr relate characters and their integer code points.
For example, ord( A ) is 65 and chr(65) is A .
Mathematics: abs, divmod, pow, round, and sum provide common mathematical
functionality; an additional math module will be introduced in Section 1.11.
Ordering: max and min apply to any data type that supports a notion of compar-
ison, or to any collection of such values. Likewise, sorted can be used to produce
an ordered list of elements drawn from any existing collection.
Collections/Iterations: range generates a new sequence of numbers; len reports
the length of any existing collection; functions reversed, all, any, and map oper-
ate on arbitrary iterations as well; iter and next provide a general framework for
iteration through elements of a collection, and are discussed in Section 1.8.

www.it-ebooks.info
Other documents randomly have
different content
PLEASE READ THIS BEFORE YOU DISTRIBUTE OR USE THIS WORK

To protect the Project Gutenberg™ mission of promoting the free


distribution of electronic works, by using or distributing this work (or
any other work associated in any way with the phrase “Project
Gutenberg”), you agree to comply with all the terms of the Full
Project Gutenberg™ License available with this file or online at
www.gutenberg.org/license.

Section 1. General Terms of Use and


Redistributing Project Gutenberg™
electronic works
1.A. By reading or using any part of this Project Gutenberg™
electronic work, you indicate that you have read, understand, agree
to and accept all the terms of this license and intellectual property
(trademark/copyright) agreement. If you do not agree to abide by all
the terms of this agreement, you must cease using and return or
destroy all copies of Project Gutenberg™ electronic works in your
possession. If you paid a fee for obtaining a copy of or access to a
Project Gutenberg™ electronic work and you do not agree to be
bound by the terms of this agreement, you may obtain a refund
from the person or entity to whom you paid the fee as set forth in
paragraph 1.E.8.

1.B. “Project Gutenberg” is a registered trademark. It may only be


used on or associated in any way with an electronic work by people
who agree to be bound by the terms of this agreement. There are a
few things that you can do with most Project Gutenberg™ electronic
works even without complying with the full terms of this agreement.
See paragraph 1.C below. There are a lot of things you can do with
Project Gutenberg™ electronic works if you follow the terms of this
agreement and help preserve free future access to Project
Gutenberg™ electronic works. See paragraph 1.E below.
1.C. The Project Gutenberg Literary Archive Foundation (“the
Foundation” or PGLAF), owns a compilation copyright in the
collection of Project Gutenberg™ electronic works. Nearly all the
individual works in the collection are in the public domain in the
United States. If an individual work is unprotected by copyright law
in the United States and you are located in the United States, we do
not claim a right to prevent you from copying, distributing,
performing, displaying or creating derivative works based on the
work as long as all references to Project Gutenberg are removed. Of
course, we hope that you will support the Project Gutenberg™
mission of promoting free access to electronic works by freely
sharing Project Gutenberg™ works in compliance with the terms of
this agreement for keeping the Project Gutenberg™ name associated
with the work. You can easily comply with the terms of this
agreement by keeping this work in the same format with its attached
full Project Gutenberg™ License when you share it without charge
with others.

1.D. The copyright laws of the place where you are located also
govern what you can do with this work. Copyright laws in most
countries are in a constant state of change. If you are outside the
United States, check the laws of your country in addition to the
terms of this agreement before downloading, copying, displaying,
performing, distributing or creating derivative works based on this
work or any other Project Gutenberg™ work. The Foundation makes
no representations concerning the copyright status of any work in
any country other than the United States.

1.E. Unless you have removed all references to Project Gutenberg:

1.E.1. The following sentence, with active links to, or other


immediate access to, the full Project Gutenberg™ License must
appear prominently whenever any copy of a Project Gutenberg™
work (any work on which the phrase “Project Gutenberg” appears,
or with which the phrase “Project Gutenberg” is associated) is
accessed, displayed, performed, viewed, copied or distributed:
This eBook is for the use of anyone anywhere in the United
States and most other parts of the world at no cost and with
almost no restrictions whatsoever. You may copy it, give it away
or re-use it under the terms of the Project Gutenberg License
included with this eBook or online at www.gutenberg.org. If you
are not located in the United States, you will have to check the
laws of the country where you are located before using this
eBook.

1.E.2. If an individual Project Gutenberg™ electronic work is derived


from texts not protected by U.S. copyright law (does not contain a
notice indicating that it is posted with permission of the copyright
holder), the work can be copied and distributed to anyone in the
United States without paying any fees or charges. If you are
redistributing or providing access to a work with the phrase “Project
Gutenberg” associated with or appearing on the work, you must
comply either with the requirements of paragraphs 1.E.1 through
1.E.7 or obtain permission for the use of the work and the Project
Gutenberg™ trademark as set forth in paragraphs 1.E.8 or 1.E.9.

1.E.3. If an individual Project Gutenberg™ electronic work is posted


with the permission of the copyright holder, your use and distribution
must comply with both paragraphs 1.E.1 through 1.E.7 and any
additional terms imposed by the copyright holder. Additional terms
will be linked to the Project Gutenberg™ License for all works posted
with the permission of the copyright holder found at the beginning
of this work.

1.E.4. Do not unlink or detach or remove the full Project


Gutenberg™ License terms from this work, or any files containing a
part of this work or any other work associated with Project
Gutenberg™.

1.E.5. Do not copy, display, perform, distribute or redistribute this


electronic work, or any part of this electronic work, without
prominently displaying the sentence set forth in paragraph 1.E.1
with active links or immediate access to the full terms of the Project
Gutenberg™ License.

1.E.6. You may convert to and distribute this work in any binary,
compressed, marked up, nonproprietary or proprietary form,
including any word processing or hypertext form. However, if you
provide access to or distribute copies of a Project Gutenberg™ work
in a format other than “Plain Vanilla ASCII” or other format used in
the official version posted on the official Project Gutenberg™ website
(www.gutenberg.org), you must, at no additional cost, fee or
expense to the user, provide a copy, a means of exporting a copy, or
a means of obtaining a copy upon request, of the work in its original
“Plain Vanilla ASCII” or other form. Any alternate format must
include the full Project Gutenberg™ License as specified in
paragraph 1.E.1.

1.E.7. Do not charge a fee for access to, viewing, displaying,


performing, copying or distributing any Project Gutenberg™ works
unless you comply with paragraph 1.E.8 or 1.E.9.

1.E.8. You may charge a reasonable fee for copies of or providing


access to or distributing Project Gutenberg™ electronic works
provided that:

• You pay a royalty fee of 20% of the gross profits you derive
from the use of Project Gutenberg™ works calculated using the
method you already use to calculate your applicable taxes. The
fee is owed to the owner of the Project Gutenberg™ trademark,
but he has agreed to donate royalties under this paragraph to
the Project Gutenberg Literary Archive Foundation. Royalty
payments must be paid within 60 days following each date on
which you prepare (or are legally required to prepare) your
periodic tax returns. Royalty payments should be clearly marked
as such and sent to the Project Gutenberg Literary Archive
Foundation at the address specified in Section 4, “Information
about donations to the Project Gutenberg Literary Archive
Foundation.”

• You provide a full refund of any money paid by a user who


notifies you in writing (or by e-mail) within 30 days of receipt
that s/he does not agree to the terms of the full Project
Gutenberg™ License. You must require such a user to return or
destroy all copies of the works possessed in a physical medium
and discontinue all use of and all access to other copies of
Project Gutenberg™ works.

• You provide, in accordance with paragraph 1.F.3, a full refund of


any money paid for a work or a replacement copy, if a defect in
the electronic work is discovered and reported to you within 90
days of receipt of the work.

• You comply with all other terms of this agreement for free
distribution of Project Gutenberg™ works.

1.E.9. If you wish to charge a fee or distribute a Project Gutenberg™


electronic work or group of works on different terms than are set
forth in this agreement, you must obtain permission in writing from
the Project Gutenberg Literary Archive Foundation, the manager of
the Project Gutenberg™ trademark. Contact the Foundation as set
forth in Section 3 below.

1.F.

1.F.1. Project Gutenberg volunteers and employees expend


considerable effort to identify, do copyright research on, transcribe
and proofread works not protected by U.S. copyright law in creating
the Project Gutenberg™ collection. Despite these efforts, Project
Gutenberg™ electronic works, and the medium on which they may
be stored, may contain “Defects,” such as, but not limited to,
incomplete, inaccurate or corrupt data, transcription errors, a
copyright or other intellectual property infringement, a defective or
damaged disk or other medium, a computer virus, or computer
codes that damage or cannot be read by your equipment.

1.F.2. LIMITED WARRANTY, DISCLAIMER OF DAMAGES - Except for


the “Right of Replacement or Refund” described in paragraph 1.F.3,
the Project Gutenberg Literary Archive Foundation, the owner of the
Project Gutenberg™ trademark, and any other party distributing a
Project Gutenberg™ electronic work under this agreement, disclaim
all liability to you for damages, costs and expenses, including legal
fees. YOU AGREE THAT YOU HAVE NO REMEDIES FOR
NEGLIGENCE, STRICT LIABILITY, BREACH OF WARRANTY OR
BREACH OF CONTRACT EXCEPT THOSE PROVIDED IN PARAGRAPH
1.F.3. YOU AGREE THAT THE FOUNDATION, THE TRADEMARK
OWNER, AND ANY DISTRIBUTOR UNDER THIS AGREEMENT WILL
NOT BE LIABLE TO YOU FOR ACTUAL, DIRECT, INDIRECT,
CONSEQUENTIAL, PUNITIVE OR INCIDENTAL DAMAGES EVEN IF
YOU GIVE NOTICE OF THE POSSIBILITY OF SUCH DAMAGE.

1.F.3. LIMITED RIGHT OF REPLACEMENT OR REFUND - If you


discover a defect in this electronic work within 90 days of receiving
it, you can receive a refund of the money (if any) you paid for it by
sending a written explanation to the person you received the work
from. If you received the work on a physical medium, you must
return the medium with your written explanation. The person or
entity that provided you with the defective work may elect to provide
a replacement copy in lieu of a refund. If you received the work
electronically, the person or entity providing it to you may choose to
give you a second opportunity to receive the work electronically in
lieu of a refund. If the second copy is also defective, you may
demand a refund in writing without further opportunities to fix the
problem.

1.F.4. Except for the limited right of replacement or refund set forth
in paragraph 1.F.3, this work is provided to you ‘AS-IS’, WITH NO
OTHER WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR ANY PURPOSE.

1.F.5. Some states do not allow disclaimers of certain implied


warranties or the exclusion or limitation of certain types of damages.
If any disclaimer or limitation set forth in this agreement violates the
law of the state applicable to this agreement, the agreement shall be
interpreted to make the maximum disclaimer or limitation permitted
by the applicable state law. The invalidity or unenforceability of any
provision of this agreement shall not void the remaining provisions.

1.F.6. INDEMNITY - You agree to indemnify and hold the Foundation,


the trademark owner, any agent or employee of the Foundation,
anyone providing copies of Project Gutenberg™ electronic works in
accordance with this agreement, and any volunteers associated with
the production, promotion and distribution of Project Gutenberg™
electronic works, harmless from all liability, costs and expenses,
including legal fees, that arise directly or indirectly from any of the
following which you do or cause to occur: (a) distribution of this or
any Project Gutenberg™ work, (b) alteration, modification, or
additions or deletions to any Project Gutenberg™ work, and (c) any
Defect you cause.

Section 2. Information about the Mission


of Project Gutenberg™
Project Gutenberg™ is synonymous with the free distribution of
electronic works in formats readable by the widest variety of
computers including obsolete, old, middle-aged and new computers.
It exists because of the efforts of hundreds of volunteers and
donations from people in all walks of life.

Volunteers and financial support to provide volunteers with the


assistance they need are critical to reaching Project Gutenberg™’s
goals and ensuring that the Project Gutenberg™ collection will
remain freely available for generations to come. In 2001, the Project
Gutenberg Literary Archive Foundation was created to provide a
secure and permanent future for Project Gutenberg™ and future
generations. To learn more about the Project Gutenberg Literary
Archive Foundation and how your efforts and donations can help,
see Sections 3 and 4 and the Foundation information page at
www.gutenberg.org.

Section 3. Information about the Project


Gutenberg Literary Archive Foundation
The Project Gutenberg Literary Archive Foundation is a non-profit
501(c)(3) educational corporation organized under the laws of the
state of Mississippi and granted tax exempt status by the Internal
Revenue Service. The Foundation’s EIN or federal tax identification
number is 64-6221541. Contributions to the Project Gutenberg
Literary Archive Foundation are tax deductible to the full extent
permitted by U.S. federal laws and your state’s laws.

The Foundation’s business office is located at 809 North 1500 West,


Salt Lake City, UT 84116, (801) 596-1887. Email contact links and up
to date contact information can be found at the Foundation’s website
and official page at www.gutenberg.org/contact

Section 4. Information about Donations to


the Project Gutenberg Literary Archive
Foundation
Project Gutenberg™ depends upon and cannot survive without
widespread public support and donations to carry out its mission of
increasing the number of public domain and licensed works that can
be freely distributed in machine-readable form accessible by the
widest array of equipment including outdated equipment. Many
small donations ($1 to $5,000) are particularly important to
maintaining tax exempt status with the IRS.

The Foundation is committed to complying with the laws regulating


charities and charitable donations in all 50 states of the United
States. Compliance requirements are not uniform and it takes a
considerable effort, much paperwork and many fees to meet and
keep up with these requirements. We do not solicit donations in
locations where we have not received written confirmation of
compliance. To SEND DONATIONS or determine the status of
compliance for any particular state visit www.gutenberg.org/donate.

While we cannot and do not solicit contributions from states where


we have not met the solicitation requirements, we know of no
prohibition against accepting unsolicited donations from donors in
such states who approach us with offers to donate.

International donations are gratefully accepted, but we cannot make


any statements concerning tax treatment of donations received from
outside the United States. U.S. laws alone swamp our small staff.

Please check the Project Gutenberg web pages for current donation
methods and addresses. Donations are accepted in a number of
other ways including checks, online payments and credit card
donations. To donate, please visit: www.gutenberg.org/donate.

Section 5. General Information About


Project Gutenberg™ electronic works
Professor Michael S. Hart was the originator of the Project
Gutenberg™ concept of a library of electronic works that could be
freely shared with anyone. For forty years, he produced and
distributed Project Gutenberg™ eBooks with only a loose network of
volunteer support.
Project Gutenberg™ eBooks are often created from several printed
editions, all of which are confirmed as not protected by copyright in
the U.S. unless a copyright notice is included. Thus, we do not
necessarily keep eBooks in compliance with any particular paper
edition.

Most people start at our website which has the main PG search
facility: www.gutenberg.org.

This website includes information about Project Gutenberg™,


including how to make donations to the Project Gutenberg Literary
Archive Foundation, how to help produce our new eBooks, and how
to subscribe to our email newsletter to hear about new eBooks.
back
back
back
back
Welcome to our website – the ideal destination for book lovers and
knowledge seekers. With a mission to inspire endlessly, we offer a
vast collection of books, ranging from classic literary works to
specialized publications, self-development books, and children's
literature. Each book is a new journey of discovery, expanding
knowledge and enriching the soul of the reade

Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.

Let us accompany you on the journey of exploring knowledge and


personal growth!

ebookball.com

You might also like