DEV Community

Cover image for 8 Coolest Python Programming Language Features
Jeremy Grifski
Jeremy Grifski

Posted on • Originally published at therenegadecoder.com on

8 Coolest Python Programming Language Features

After writing nearly 20 articles just about Python, I’ve decided to take some time to reflect on what I’ve learned. For instance, I recently wrote a compilation article which includes 70+ Python code snippets. Now, I’ve put together a list of some of the coolest Python programming language features.

Coolest Python Features List

And without further ado, let’s take a look at some of the coolest Python features. If you think I’ve missed any, feel free to drop them in the comments.

List Comprehensions

By far, my favorite feature in Python is the list comprehension. Honestly, the feature isn’t all that interesting; it’s just a convenient way to generate lists. That said, it’s a feature that I haven’t seen in any other popular language (e.g. Java, C, C++, etc.). As a result, I make sure to take advantage of it as often as possible. Here are a few examples:

# Generates a list containing values from 0 to 9
[i for i in range(10)]

# Generates a list of all even values from 0 to 9
[i for i range(10) if i % 2 == 0]

# Generates a list containing values from 1 to 10
[i + 1 for i in range(10)]

# Generates a list containing values from 0 to -9
[-i for i in range(10)]

# Generates all possible pairs between 0 and 9
[(a, b) for a in range(10) for b in range(10)]

# Shallow copies another list
my_list = [1, 3, 5, 7, 9]
[item for item in my_list]
Enter fullscreen mode Exit fullscreen mode

Since a list comprehension creates a list, we’re able to work with the output like any other list:

# Generates a list containing values from 0 to 9
nums = [i for i in range(10)]
nums[0] # returns 0
nums[1] # returns 1
Enter fullscreen mode Exit fullscreen mode

If you’re interested in learning how to write these yourself, I have an article just for you. In it, you’ll learn more about the syntax as well as a few application areas. If you have any of your own examples, feel free to share them in the comments.

Generator Expressions

One of the nice things about learning the list comprehension syntax is that it allows you to also write generator expressions. After all, they’re very similar—one just saves you space. That’s right! Generator expressions don’t actually create lists. Instead, they provide the means for generating one item at a time of a list without ever constructing that list. Take a look:

# Generates values from 0 to 9
(i for i in range(10)])

# Generates values from 0 to 9
(i for i range(10) if i % 2 == 0)

# Generates values from 1 to 10
(i + 1 for i in range(10)])

# Generates values from 0 to -9
(-i for i in range(10))

# Generates all possible pairs between 0 and 9
((a, b) for a in range(10) for b in range(10))

# Generates a shallow copy of another list
my_list = [1, 3, 5, 7, 9]
(item for item in my_list)
Enter fullscreen mode Exit fullscreen mode

Notice how similar the syntax is to the list comprehension. However, the application is slightly different. Instead of indexing the elements, we have to use a special function:

# Generates values from 0 to 9
nums = (i for i in range(10)])
next(num) # returns 0
next(num) # returns 1
Enter fullscreen mode Exit fullscreen mode

Since a generator is an iterable, we can also get away with using the for loop syntax:

# Generates values from 0 to 9
nums = (i for i in range(10)])
for num in nums: 
    print(num) # prints each item in the generator
Enter fullscreen mode Exit fullscreen mode

Once we’ve exhausted every element, the generator expression becomes useless. In other words, we can only generate every element once. After that, we have to write the expression again.

Slice Assignment

Have you ever wanted to replace entire sections of a list? Well, Python has a feature that allows you to do just that in a single line: slice assignment. Like slicing, slice assignment allows you to specify a region of a list. Of course, the difference is that slice assignment then lets you replace that region with whatever you want:

my_list = [1, 2, 3]

# Appending a list with slice assignment
my_list[len(my_list):] = [4]

# Prepending a list with slice assignment
my_list[:0] = [0]

# Replacing middle element
midpoint = len(my_list) // 2
my_list[midpoint: midpoint + 1] = [-2]

# Replacing arbitrary subsection
my_list[:2] = [3, 4, 5]
Enter fullscreen mode Exit fullscreen mode

As I’ve mentioned in a related article, slice assignment doesn’t stop there. We can use any iterable on the right side. For example, we could use strings, tuples, list comprehensions, or even generator expressions. In other words, our previous two features can make an appearance:

my_list = [1, 2, 3]
my_list[len(my_list):] = (item for item in range(5))
Enter fullscreen mode Exit fullscreen mode

Since learning about slice assignment in late 2019, I’ve been obsessed with it. As a result, I think it’s my second favorite feature right behind list comprehensions. Right now, I don’t have an article covering this feature in more detail, so you’re welcome to share some of your favorite examples in the comments.

Iterable Unpacking (aka Destructuring)

If you’ve checked out my article on getting the last item of a list, you might recall that iterable unpacking was one of the solutions. The idea being that we can split a list into two pieces: the last item and everything else:

my_list = [1, 2, 3]
*remainder, last_item = my_list
Enter fullscreen mode Exit fullscreen mode

Well, iterable unpacking can do more than retrieve the end of a list. For example, it can be used to swap variables:

a = 1
b = 2
b, a = a, b
Enter fullscreen mode Exit fullscreen mode

Normally, we’d need three lines of code to perform a swap: one to create a temporary variable, another to overwrite one of the variables, and the last to copy the temporary variable to the other variable. With iterable unpacking, it’s a single line of code.

If iterable unpacking looks familiar to you, you might know it from its other name: destructuring. Oddly enough, I featured destructuring in an article covering some of my favorite features of any programming language.

That said, I don’t use iterable unpacking very often. If you have any good examples that would supplement this list, feel free to share them.

Negative Indexing

Of all the features on this list, negative indexing is perhaps the most subtle. After all, many modern programming languages have some form of list indexing. However, few have a way of getting the last element of a list so elegantly:

my_list = [1, 2, 3]
last_item = my_list[-1]
Enter fullscreen mode Exit fullscreen mode

In addition to being able to access list elements in reverse, we can also use negative indexing with list methods like insert(), pop(), and index():

my_list = ['h', 'e', 'l', 'l', 'o']
my_list.insert(-1, 'l') # ['h', 'e', 'l', 'l', 'l', 'o']
my_list.pop(-2) # ['h', 'e', 'l', 'l', 'o']
my_list.index('l', -2) # 3
Enter fullscreen mode Exit fullscreen mode

If you like negative indexing, you’ll be happy to know this feature doesn’t stop with lists. Feel free to use it with strings, tuples, and other sequences.

Dictionary Comprehensions

Previously in this list, I mentioned list comprehensions. Apparently, that feature is so good that the developers decided to expand its capabilities to encompass other data structures like dictionaries. After all, wouldn’t it be nice to be able to generate a dictionary in a single line of code? Well, as of PEP 274, you can:

# Generates a dictionary of numbers to letters
{num: chr(65 + num) for num in range(5)} 

# Generates the same thing
nums = [1, 2, 3, 4, 5]
letters = ["A", "B", "C", "D", "E"]
{num: letter for num, letter in zip(nums, letters)}
Enter fullscreen mode Exit fullscreen mode

Typically, I use a dictionary comprehension to merge two lists into a dictionary. That said, I’m sure there are other use cases. Feel free to share some of your favorite it in the comments.

Chaining Comparisons

In many modern programming languages, comparing values is a simple process. For example, in Java, I can compare two numbers as follows:

17 > 5
Enter fullscreen mode Exit fullscreen mode

In this example, the result is a boolean, true. As a result, the following expression is illegal in Java:

17 > 5 > 1
Enter fullscreen mode Exit fullscreen mode

Here, 17 > 5 evaluates to true. Then, the expression true > 1 is evaluated. Since this is nonsensical, the compiler crashes.

In Python, however, we can chain comparisons without any risks. In other words, the same expression above is perfectly valid, and it returns True.

Under the hood, each comparison is computed just like Java. However, each intermediate result is ANDed with the result of the other comparison. For example, 17 > 5 returns True. Then, 5 > 1 returns True. Finally, the results are combined by and which returns True.

Personally, I haven’t used this feature much, but it’s gotten a lot of attention on the development end. For example, PEP 535 mentions a few updates to the chaining protocol. If you know of any cool use cases for this feature, let me know in the comments.

f-Strings

Finally, we come to one of my favorite “new” (PEP 498) Python features, f-Strings. Normally, when we create strings for debugging, we lazily print them with concatenation. If we’re clever, we might use some of the string formatting techniques. Now, we can get the best of both worlds with f-Strings:

age = 25
name = 'Jeremy'
print(f'My name is {name}, and I am {age}')
Enter fullscreen mode Exit fullscreen mode

In this example, we’ve created a string from two variables: name and age. All we had to do was prepend our string with an f. Then, we can place any expression we want in braces, and it will be interpreted. For example, age is a number which is automatically converted to its string representation.

I really love this f-String syntax because it solves a lot of common string formatting issues. For example, it makes string formatting very easy to read (unlike concatenation). Likewise, it makes it obvious what the output string will look like (again, unlike concatenation). Finally, there’s no issues with positioning of variables (unlike string interpolation). What you see is what you get.

While f-Strings are really helpful, I don’t find myself using them beyond debugging. Do you have any examples you’d like to share?

Honorable Mentions

As someone who really loves working with Python, I had a hard time keeping this list short. As a result, here are a few additional features that didn’t make the cut:

  • For/Else loops
  • Imaginary numbers
  • Any() and All()
  • Returning multiple values (tuples)
  • Arbitrarily large integers
  • Keyword arguments
  • Sets
  • Joining strings
  • Multiplying strings
  • Walrus operator
  • String interpolation
  • Slicing

Of course, with how enormous the standard library is in Python, I’m sure there are even more clever bits of syntax. In addition, Python development is very active, so I wouldn’t be surprised to see even more features in the future. Perhaps I’ll update this list from time to time as new features appear.

Recommendations

With all that said, thanks for sticking around to check out this list. Over the next couple months, I’ll be focusing more on Python and Git content, so expect to see more articles like this in the future. If there’s anything you’d like to see, drop a note in the comments or feel free to contact me directly.

In the meantime, support this website by hopping on the mailing list, becoming a patron, or exploring the shop. Otherwise, keep browsing the following related articles:

Otherwise, thanks again for your time. I appreciate it!

The post 8 Coolest Python Programming Language Features appeared first on The Renegade Coder.

Latest comments (8)

Collapse
 
elfjes profile image
Pelle Koster

Negative indexing is great. Not only for the -1: give me the last item, but also for -2: give me the second to last value. Also: it auto-wraps around. List of length 3? Index -4 brings you right back to the end. Great alternative for % (modulo) indexing and/or itertools.cycle. Be careful though, it might not make your code more readable, so be sure to express intent

Collapse
 
renegadecoder94 profile image
Jeremy Grifski

It seems the language has a lot of cool stuff in it. My only worry is that these features will increase the complexity of the language rather than improving it, but I haven't really seen that yet!

Collapse
 
sobolevn profile image
Nikita Sobolev • Edited

Awesome post! I really love Python. But, sometimes there are just too many awesome features in your code that make it not so awesome anymore.

To fight this I recommend using wemake-python-styleguide: it is a tool to help you to write beautiful, meaningful, simple, and working Python.

Check it out, if you love elegant code!

GitHub logo wemake-services / wemake-python-styleguide

The strictest and most opinionated python linter ever!

wemake-python-styleguide

wemake.services Supporters Build Status Coverage Status Python Version wemake-python-styleguide


Welcome to the strictest and most opinionated python linter ever.

wemake-python-styleguide logo

wemake-python-styleguide is actually a flake8 plugin with some other plugins as dependencies.

Quickstart

pip install wemake-python-styleguide

You will also need to create a setup.cfg file with the configuration.

We highly recommend to also use:

  • flakehell for easy integration into a legacy codebase
  • nitpick for sharing and validating configuration across multiple projects

Running

flake8 your_module.py

This app is still just good old flake8 And it won't change your existing workflow.

invocation resuts

See "Usage" section in the docs for examples and integrations.

We also support Github Actions as first class-citizens Try it out!

What we are about

The ultimate goal of this project is to make all people write exactly the same python code.



































flake8 pylint black mypy wemake-python-styleguide
Formats code?
Finds style issues? 🤔 🤔
Finds bugs? 🤔




Collapse
 
iceorfiresite profile image
Ice or Fire

Good post! My favorites are list comprehensions and f-strings.

Collapse
 
fronkan profile image
Fredrik Sjöstrand • Edited

Thanks for a nice post. I had never heard about the chaining comparison. I love it!

A note on the dictionary compression.
If you just want to combine to lists to a dictionary you could also use:

dict(zip(list1,list2))

Where I think the dictionary compression really shines is if you need to do some filtering when creating the dictionary

Collapse
 
fronkan profile image
Fredrik Sjöstrand

I also use dictionary compressions when mapping from a 2D arrays where I want the key to be the value of one of the columns.

Some comments may only be visible to logged-in visitors. Sign in to view all comments.