Sign in

4 Python Concepts That Beginners May Be Confused About

Virtual environments, string interpolation, lazy evaluation, and comprehensions

Photo by Robert Reyes on Unsplash.

Learning a new programming language is not easy, especially if you don’t have any previous programming experience. However, learning Python is arguably more straightforward than learning several other languages because it endorses the REPL (Read-Eval-Print-Loop) learning approach for beginners. Simply put, to learn Python, we can just use a command console. You write your Python code (e.g. print(“Hello, World!”)), and the console will evaluate the code and print the output as applicable. This REPL approach provides real-time feedback about varied topics in Python, which makes Python learning straightforward.

Despite this handy learning approach, there are some concepts that may be confusing to Python beginners. In this article, I’d like to focus on clarifying four concepts.

1. Virtual Environment

Beginners won’t find the concept of virtual environments relevant until they start working on some real projects. Take the following scenario: In one project, you use a particular package (A) that depends on version 1.0 of package X. However, in another project, you use package B, which depends on version 1.5 of package X.

Here’s the dilemma you’re running into: If you install X v1.0, your second project can’t operate. However, if you install X v1.5, your first project can’t operate. Do we have to use two different computers for these projects? Certainly, this expensive approach will work, but what if you have multiple projects? It’s definitely impractical to have separate computers for different projects.

To address the possible conflicts between different projects, there is a smart solution that prior Python programmers have already developed for us — the virtual environment. The overall idea is that we create isolated work environments for each of our projects such that the versions of the packages in one project won’t have conflicts with other incompatible versions of the same packages in other projects.

There are several approaches for managing virtual environments, such as venv and conda. Just to provide with you a proof of concept, the following code shows you the common manipulations of virtual environments using the venv module, which is part of the standard Python library.

  • After you navigate to a desired directory, to create a virtual environment, run the following in your command-line tool (e.g. Terminal for Mac): python3 -m venv medium-env. Please note that medium-env specifies the environment that you're creating. It also assumes that you’ve already have installed Python 3 on your computer.
  • Once the virtual environment is created, you can activate the environment by running the following code on your Mac (note that Windows uses a different command): source medium-env/bin/activate.
  • From now on, you’ll see that your Terminal prompt has a prefix of (medium-env), which indicates that you’re working in the virtual environment as you’re supposed to be. You can do whatever you need to do, such as installing new packages.
  • Once you’re done with your work, you can leave the virtual environment by simply running deactivate.

If you’re new to virtual environments, it’s easier to set one up by installing Anaconda, which will take care of your Python interpreter, package management, and virtual environment. For more details, please visit Anaconda’s website.

2. String Interpolation (F-Strings)

Needing to prepare strings in an applicable format such that we can present them is a common task. Conventionally, there are a couple of ways to format the strings — one using the format function and the other using C-style %-based formatting. Some trivial examples are shown below:

Conventional string formatting

As shown in the code snippet above, these two approaches separate the string texts from the desired formats. For instance, if we want to format three numbers as shown below, we’ll do the following thing using the format function. As you may have noticed, we’ll have to map each variable to each format, which can be confusing if we miss a number or variable.

Number formatting

By contrast, string interpolation or literal string interpolation, which was introduced in Python 3.6, has made string formatting much easier and more importantly more readable. To format the numbers as shown in the code snippet, we can do the same thing using the string interpolation technique.


  • We use the letter f to denote that we’re creating the f-string.
  • Similarly to the format function, f-strings use curly braces to indicate the variables that are to be interpolated.
  • Unlike with the format function, each interpolation has the variable and the desired formatting, which eliminates the physical distance between them and makes the string more readable.

3. Lazy Evaluation

Lazy evaluation is computer programming jargon that refers to data (e.g. variables) that are not fetched/prepared until they’re requested. For instance, in Swift, we can use the lazy keyword to denote a variable such that it’s not calculated until we call it. Although Python doesn’t have lazy as a keyword, the same lazy evaluation is still available in Python.

For one example, we can have lazy attributes for our custom class instances. The following code shows you how we can use the property decorator to realize this functionality (please feel free to explore the @cached_property decorator in the functools module for a similar effect):

Lazy attribute using property

  • In the initialization method (i.e. __init__), we set the protected attribute (_profile_data) to be None, which simply serves as a placeholder. In many cases, we don’t really need the profile data.
  • However, if we do need to get the profile data, we can wrap it around a property decorator. It will check if the _profile_data is None or not, and it will only run the expensive web request when we don’t have data for the _profile_data attribute.

For another example, generators in Python also take advantage of the lazy evaluation technique. As you may know, generators are a special kind of iterator that render elements when they’re requested. Unlike some common iterators created from lists and dictionaries, generators don’t have all of their elements loaded in the memory, and thus they’re very memory-efficient. It’s all because they hold the state of the iteration and “lazily” render the next applicable item. The following code shows you related usage of generators:

Memory efficiency of generators

  • We use the so-called generator expression to create a simple generator that renders squares.
  • Compared to the list counterpart, the generator has only a tiny fraction of the size that the list occupies (96 bytes vs. 9,000 bytes). However, both achieve the same effect — the sums of both are equal.

4. Comprehensions

One of the cool Python features is the comprehension technique. Even for beginners, list comprehension is probably one of the advanced techniques that they’ve heard of. The purpose of using list comprehension is to create a list object using an iterable in a very concise way. As a matter of fact, I used the list comprehension in the previous section to create this list of squares:

List comprehension

  • The list comprehension has the following syntax: [expression for x in iterable]. In the example above, we use the range object.
  • If we don’t use list comprehension, we can use a for loop to iterate the range object and append the square to the list object. In the end, both lists have the same items. However, list comprehension is apparently a more concise way to create list objects and should be the preferred way to create a list object if we start with an iterable.

Besides list comprehension, Python also has comprehension techniques to create dictionaries and sets. The following code snippet shows you the usage:

Dict and set comprehensions

  • The dictionary comprehension has the following syntax: {key_expr: valu_expr for x in iterable}.
  • The set comprehension has the following syntax: {expr for x in iterable}.


In this article, we reviewed four concepts that beginners may be confused about. Here’s a recap of these concepts:

  • Virtual environments are a way that we can create isolated workspaces for our projects such that they can have different Python versions and distinct dependency requirements.
  • String interpolation is known as the f-string in Python, which is a more readable way to create formatted strings by having the relevant variable/expression next to the applicable formatting settings.
  • Lazy evaluation is a programming technique that allows our program to delay the expensive operations (e.g. a web request, a computationally heavy calculation) as much as possible.
  • Comprehensions are a technique that allows us to create lists, dictionaries, and sets in a much more concise way, which eliminates the need to use a for loop.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store