💡
My Docs
BlogLinkedin
WEB_DEV_JOB_SEARCH
WEB_DEV_JOB_SEARCH
  • Home
  • 🏡Home
  • 🗺️Navigation
  • 📥Useful Downloads
  • TO DO
    • Meetings:
    • Take Home Assignments
  • Jobs To Apply To
  • 🛠️Skills
    • 🍢My Stack
    • E-Engineering
    • SQL / PSQL
  • 📋Filling Out Forms
  • 📖Resources
    • Linkedin Cheat Shee
    • Job Search Advice
    • Orientation:
    • Links
    • Running List Of MISC Resources:
    • ❄️Cold Outreach Generator
  • Profiles
  • Linkedin
  • Examples
  • Resume
    • Resume
      • Certificate (Lambda)
      • Examples
      • Advice
      • Dice
      • Linkedin Resume
      • Indeed Resume
  • Applications
    • 🖱️TRACKING_APPLICATIONS
    • Amazon
  • Applications & Job Postings
    • Job Boards
      • More Job Boards
    • 📮Postings:
      • Avid / Pro Tools
      • Amazon
      • My Applications
        • Application Info
        • In Progress
      • First Round Of Applications
      • Jobs To Keep Track Of
      • Recommended Jobs
  • Cover Letter
    • Cover Letter
      • CV-Guidance
    • More Advice
      • Practice Problems:
    • Example
    • Example Of Developer Bio
    • Old Engineering Cover Letter
  • Portfolio
    • 💾Git Repo
    • 🖼️Portfolio
  • 📈Slack&Lambda
    • 📺Recordings
    • 🧑‍🤝‍🧑🧑🤝🧑 🧑🤝🧑 🧑People
  • Aux-Resources
    • Youtube
    • 👨‍🏫👨🏫 👨🏫 👨Guidance
  • 🖋️Interview Prep
    • INTERVIEW
    • 👨‍💻👨💻 👨💻 👨💻 👨💻 👨💻 👨💻 👨💻 Leetcode
      • 37-Essential-Js-Questions
      • 📈Rubric
    • Resources
      • List of List
      • Cheat-Sheet
    • Cheat-Sheet-Raw
    • General Advice & Tips
      • Website Checklist
      • Phone Interview Advice
    • Overview
      • Data-Structures Q & A
    • Web Dev Interview Questions
      • FULL-STACK DEVELOPER INTERVIEW QUESTIONS AND ANSWERS
    • ⁉️Interview Questions.
      • cross-site scripting attack (XSS) and how do you prevent it?
      • What are refs in React? When should they be used?
      • virtual DOM and why is it used in libraries/frameworks?
      • What does the following code evaluate to?
      • What is the this keyword and how does it work?
      • What are landmark roles and how can they be useful?
      • What is the difference between lexical scoping and dynamic scoping?
      • What is the difference between null and undefined?
      • What is CSS BEM?
      • What is HTML5 Web Storage? Explain localStorage and sessionStorage.
      • How can you avoid callback hells?
      • What is functional programming?
      • useful example of one?
      • What is an async function?
      • What is the difference between the equality operators == and ===?
      • use-strict
      • sync-vs-async
      • null-vs-undefined
      • promises
      • accessibility-tree
        • imperative-vs-declarative
      • bem
      • cors
      • alt-attribute
    • Qualitative Questions
      • Cheat Sheets
        • Python-VS-JS Cheat Sheet
        • 🐍Python
      • React Interview
        • React Questions:
      • Front End Questions
    • 🧮DS_ALGO Practice:
      • Algorithms
      • Exampes
      • DS_ALGO_NOTES
        • The queue data structure (JS)(PY)
    • Behavorial
      • Python Subpage
      • DS_&_ALGO_STUDY_GUIDE
      • Intro 2 Graphs:
      • Graphs
        • Graph (py)
      • Free Code Camp
      • Types Of Data Structures
      • Arrays
      • Page 2
      • 🥅Hash Tables
    • FANG PREP (medium article)
    • ⏱️More Practice:
    • 300 React Q & A's
      • 💸React Tips
    • Redux
    • 🛕Examples
      • Representing A Graph:
      • Anagrams & Big O
        • Python Performance
        • Strongly Connected Graph
      • Gists
    • Common Knowledge Questions
  • Tutorials
    • Custom Outreach Message Generator
      • Common Questions
      • Self Introduction
  • Technical Interview Tutorial
  • Job Boards
    • 📋Job Boards
      • Less Promising Job Boards
      • LIST OF BOARDS
  • Networking
    • 🗓️Events
  • MISC
    • Articles To Read
    • Job Search Images
  • Notes
    • Interview Navigation
    • Notes
    • CSS Interview Prep Quiz
  • 🖨️Interviewing
    • General
    • Inspiration
    • Front End Interview
    • Common Questions
  • Networking
    • Networking
      • a/A Email List
    • Page 1
  • 📓ARCHIVE
    • Archive
      • ❇️Slack Announcements
    • Projects
Powered by GitBook
On this page
  • Lists
  • Dictionaries

Was this helpful?

Edit on GitHub
  1. Interview Prep
  2. Examples
  3. Anagrams & Big O

Python Performance

PreviousAnagrams & Big ONextStrongly Connected Graph

Last updated 3 years ago

Was this helpful?

Now that you have a general understanding of big O notation, we’re going to spend some time discussing the big O performance for the most commonly-used operations supported by Python lists and dictionaries. The efficiencies of these data types are important because we’ll be using them to implement other abstract data structures for the remainder of this book.

This section is intended to give you some intuitive understanding of why the performances are what they are, but you won’t fully appreciate these reasons until later, when we explore how lists and dictionaries can be implemented.

Keep in mind that there is a difference between the Python language and a . Our discussion below assumes the use of the CPython implementation.

Lists

The designers of the Python list data type had many choices to make during implementation. Each choice affected how quickly the list could perform operations. One decision they made was to optimize the list implementation for common operations.

Indexing & Assigning

Two common operations are indexing and assigning to an index position. In Python lists, values are assigned to and retrieved from specific, known memory locations. No matter how large the list is, index lookup and assignment take a constant amount of time and are thus O(1)O(1)O(1).

Appending & Concatenating

Another common programming need is to grow a list. There are two ways to do this: you can use the append method or the concatenation operator (+).

The append method is “amortized” O(1)O(1)O(1). In most cases, the memory required to append a new value has already been allocated, which is strictly O(1)O(1)O(1). Once the C array underlying the list has been exhausted, it must be expanded in order to accomodate further appends. This periodic expansion process is linear relative to the size of the new array, which seems to contradict our claim that appending is O(1)O(1)O(1).

However, the expansion rate is cleverly chosen to be three times the previous size of the array; when we spread the expansion cost over each additional append afforded by this extra space, the cost per append is O(1)O(1)O(1) on an amortized basis.

On the other hand, concatenation is O(k)O(k)O(k), where kkk is the size of the concatenated list, since kkk sequential assignment operations must occur.

Popping, Shifting & Deleting

Popping from a Python list is typically performed from the end but, by passing an index, you can pop from a specific position. When pop is called from the end, the operation is O(1)O(1)O(1), while calling pop from anywhere else is O(n)O(n)O(n). Why the difference?

When an item is taken from the front of a Python list, all other elements in the list are shifted one position closer to the beginning. This is an unavoidable cost to allow O(1)O(1)O(1) index lookup, which is the more common operation.

For the same reasons, inserting at an index is O(n)O(n)O(n); every subsequent element must be shifted one position closer to the end to accomodate the new element. Unsurprisingly, deletion behaves the same way.

Iteration

Slicing

Multiplying

Reversing

Sorting

For reference, we’ve summarized the performance characteristics of Python's list operations in the table below:

Operation
Big O Efficiency

index []

index assignment

append

pop()

pop(i)

insert(i, item)

del operator

iteration

contains (in)

get slice [x:y]

del slice

reverse

concatenate

sort

multiply

Dictionaries

We won't try to provide an intuitive explanation for this now, but rest assured that we’ll discuss dictionary implementations later. For now, simply remember that dictionaries were created specifically to get and set values by key as fast as possible.

contains

Iterating & Copying

We’ve summarized the efficencies of all dictionary operations in the table below:

Operation
Big O Efficiency

copy

get item

set item

delete item

contains (in)

iteration

The “Average Case”


Iteration is O(n)O(n)O(n) because iterating over nnn elements requires nnn steps. This also explains why the in operator in Python is O(n)O(n)O(n): to determine whether an element is in a list, we must iterate over every element.

Slice operations require more thought. To access the slice [a:b] of a list, we must iterate over every element between indices a and b. So, slice access is O(k)O(k)O(k), where kkk is the size of the slice. Deleting a slice is O(n)O(n)O(n) for the same reason that deleting a single element is O(n)O(n)O(n): nnn subsequent elements must be shifted toward the list's beginning.

To understand list multiplication, remember that concatenation is O(k)O(k)O(k), where kkk is the length of the concatenated list. It follows that multiplying a list is O(nk)O(nk)O(nk), since multiplying a kkk-sized list nnn times will require k(n−1)k(n - 1)k(n−1) appends.

Reversing a list is O(n)O(n)O(n) since we must reposition each element.

Finally (and least intuitively), is O(nlog⁡n)O(n\log{n})O(nlogn) and to demonstrate.

The second major Python data type is the dictionary. As you might recall, a dictionary differs from a list in its ability to access items by key rather than position. For now, the most important characteristic to note is that “getting” and “setting” an item in a dictionary are both O(1)O(1)O(1) operations.

Another important dictionary operation is checking whether a key is present in a dictionary. This “contains” operation is also O(1)O(1)O(1) because checking for a given key is implicit in getting an item from a dictionary, which is itself O(1)O(1)O(1).

Iterating over a dictionary is O(n)O(n)O(n), as is copying the dictionary, since nnn key/value pairs must be copied.

The efficiences provided in the above tables are performances in the average case. In rare cases, “contains”, “get item” and “set item” can degenerate into O(n)O(n)O(n) performance but, again, we’ll discuss that when we talk about different ways of implementing a dictionary.

Python is still an evolving language, which means that the above tables could be subject to change. The latest information on the performance of Python data types can be found on the Python website. As of this writing, the Python wiki has a nice time complexity page that can be found at the .

🖋️
🛕
O(1)O(1)O(1)
O(1)O(1)O(1)
O(1)O(1)O(1)
O(1)O(1)O(1)
O(n)O(n)O(n)
O(n)O(n)O(n)
O(n)O(n)O(n)
O(n)O(n)O(n)
O(n)O(n)O(n)
O(k)O(k)O(k)
O(n)O(n)O(n)
O(n)O(n)O(n)
O(k)O(k)O(k)
O(nlog⁡n)O(n\log{n})O(nlogn)
O(nk)O(nk)O(nk)
O(n)O(n)O(n)
O(1)O(1)O(1)
O(1)O(1)O(1)
O(1)O(1)O(1)
O(1)O(1)O(1)
O(n)O(n)O(n)
Time Complexity Wiki
Python implementation
sorting in Python
beyond the scope of this book