Transcript
This transcript was autogenerated. To make changes, submit a PR.
Hello everyone, I'm Amara from Pakistan. I have been working with Python
for more than six years now, and in today's talk I
will be discussing about some common Python idioms and why it is important
to write pythonic code, how it relates to the quality
of the code, and what tools are available to check for the quality,
or to make sure that your code is following the language guidelines.
Let's get started. First of all, a brief outline.
I will be discussing that what is pythonic and why it is important
to write pythonic code? What is code quality and why it is important
to measure what tools are available for Python programmers to make sure
that their code bases are following Python guidelines.
What is idiomatic Python? And in the end, I will be sharing some common
pythonic idioms which I have learned through over the years.
So let's get started. First of all, what is pythonic?
Any program, function or block of code that follows style guidelines
and make use of Python's unique capabilities or language features is said
to be pythonic code. Snippet writing pythonic code
is important because that determines that your code is
of certain quality and certain standard. It follows
language features and you are adhering to the language standard and industry
standards for that language. It also counts for these
quality of the code. And code quality is getting
important day by day due to scarcity of
the trained resources. Now, when we talk about quality
of the code, what do we mean by that? If you quickly
search through the Google can get to know that what are the attributes
of a good code? Quality good quality code. But we can summarize
them in the following points that it does what it is supposed
to do. A certain code snippet is supposed to perform a
set of basic requirements. If it is not performing those requirements, then it is
not even a bad quality code. So it should be performing what it is supposed
to do. Then there are known defects and problems. For this,
I will take an analogy of these detergent
you use to wash your clothes. If your detergent is working fine
with day to day clothes which are not having any
hard stains, but whenever a hard stain gets
onto your clothes, this detergent cannot perform in
getting rid of that stain, then your detergent is not of
good quality. And the third and most important attribute
of a good quality code is that it is readable,
maintainable and extendable. It should be maintainable and extendable because
over the time, as the requirements change and businesses processes
grow, you have to add new functionality. If you are not able to
extend your existing code, then you will have to rewrite the whole
software again. And it should be readable because it is not necessary that the
person who wrote the software first will be available to maintain
and extend the software forever. You will be hiring new
engineers and it should be readable enough so that new engineers
or new developers can easily understand your code. So why
code quality is important? Code quality is important because of the following reasons.
First of all, clarity. If your code is not of good
quality, then these will not give the clarity to the people who
are working on the code basis. And it will not
give the clarity that how a certain requirement is being accomplished
through the code written. Then the second reason is efficiency.
If your code is of bad quality and it is not
readable, or maintainable or extendable, then the cost of
maintaining such project or extending such project will skyrocket and
your budgets will be affected. And it will not be efficient in
terms of finances and human resources as well.
The third important reason is the credibility. If you are
following certain quality standards while writing your code, then it will add
to your credibility as a programmer. But if you are not following
the standards and guidelines, then your credibility as
a Python programmer will diminish and that will definitely harm
you in the long run. So as Python programmers, what tools
are available to make sure that the code we are writing follows a
certain set of guidelines and is of certain standard quality?
There are a lot of tools available, but I will be discussing the following three
the Zen of Python, pep eight and lenters.
Let's talk about them one by one. Zen of Python.
Zen of Python are basically 20 amorphisms written
by a python. These Tim Peters, he wrote
these beautiful, actually 19 amorphisms and left 20th,
the last one to fill in by the creator of the Python language,
Guido and Rossam. But it's still not filled in. Also,
another Pythonista who has also contributed the Python
language, Barry Warsaw, sang these amorphisms
as lyrics in May 2020. And you can
easily find that song on YouTube by
searching the Zen of Python. This set of guidelines
or this set of amorphisms is also included, as can Easter egg
in the Python distribution. If you go to the Python shell and write
import this, the Zen of Python get printed.
Now, if we look at these morphisms one by one, these are basically a
code set of principles which are being followed while writing the language.
And it is expected from all the programmers using the
language that they follow these simple principles.
Let's start with the beautiful is better than ugly,
because if your code is written beautifully and it's not cluttered,
then it will improve the readability of your code.
Explicit is better than implicit. For this, I will take the use
case of naming the variables used in your code. The variables
used in your code should follow the naming conventions set by
the language, and also the names you are assigning to the variables should
contain the context for which these variables are being used, so that
everybody reading your code can understand that what variable is
holding data for what purposes? Simple is better than
complex and complex is better than complicated.
You should try to use simple language constructs to solve
simple problems. But if you have a complex problem and
you cannot solve it by simple language constructs, then you can
use a complex solution, but it should not be overly complicated.
Flat is better than nested. This means that if
you can avoid the nesting of tools, or you can
achieve something by a flatter piece of code, then you should avoid undue
nesting. One example of this can be avoiding
nested loops by using the product method in iter
tools module. Maybe sparse is better than dense,
so this is related to spaces and indentation
levels. Indentation spaces in the code
base you are dealing with. If it is sparse,
it has more spaces, then it is better for readability because readability
counts. Special cases aren't special enough to break the rules,
although practicality beats purity. Yes,
you should not break the rules of the language to handle
special cases in your project. But if those special cases
cannot be handled without breaking the rules,
then of course you have to follow the practicality. Errors should never
pass silently unless explicitly silenced.
This explains that you should be aware that what errors
are being thrown by your code, and you should explicitly
catch them and determine that what to
do if certain error occurs. But if you want errors
go unnoticed, then it should be explicitly silenced. That means you
should write the catch block for try accept
block, and you can write the pass statement in the accept block to silence
the error. So all these beautiful amorphisms are basically
a code set of principles which you can use to
make sure that your code is following the basic guidelines
recommended by actual Python developers who have contributed
to the language creation like this one. If the implementation
is hard to explain, it's a bad idea. If the implementation is
easy to explain, it may be a good idea, right? So next tool
we can talk about is pep eight. Pep eight are
basically what does pep stands for? PEp stands
for performance enhancement proposals, and we can define these proposals
as the documents to describe new features proposed and
to document different aspects of Python
like performance design and style for the community. These are
basic set of guidelines which your code should
be following. These include stylistic guidelines and naming conventions,
how you should lay out your code, how you should format your code.
We also have such kind of guidelines for the commenting
and doc strings in our Python code as well. That is web two five seven.
So let's look at some of the aspects of web eight.
Let's talk about the code layout one statement per line
you might know that we can write multiple statements
in one line in Python, but we have to separate them by semicolon
if we want multiple lines of code in one line. But it
is strongly recommended that you use one statement per line, and that is the
reason you can get rid of the semicolon at the end of each
statement, which was really error prone in our college
days of c plus plus projects and assignments.
Single point of return while writting Python functions,
you should consider to make sure that your function
is returning from at the end of the function at the single point.
Having multiple point of returns in a function will cause confusion,
it will be more error prone, and for the future developers, it will
difficult to understand that what you are returning from a function
in every scenario indentation we know that Python
syntax is strongly dependent upon the indentation.
We can use two spaces per indentation level and four spaces
per indentation level as well, but it is recommended
that we should use four spaces per indentation level if you
remember that sparse is better than dense from the Zen of Python.
So if you are using four spaces then your code will be a little bit
sparse and it will be more readable. Tabs or
spaces for indentation you can use tabs or spaces.
Tabs is of eight characters by default, but you can modify it
to consist of only four characters. But by the Python creators
it is recommended that spaces should be used for indentation instead
of tabs maximum line length so this is
kind of a strange requirement. But if you think about this requirement,
then you get to know that these limit of 79
characters for a single line of code in a Python editor
is actually because that you don't have to scroll from left to right again
and again to read only one line of code. So it
is limited to 79 characters only, and for the
comments and doc strings it is further limited to
72 characters only. In web two five seven. You can find
the guidelines for writing comments and doc strings in your Python code
as well. Python has a rich libraries available
to its programmers through which you can achieve various
features and various tasks readily available.
So to use these libraries you have to import those modules
and libraries in your code. So it is recommended to include
all the imports used in your code scripts at the top of
the file and each import should be at a separate line.
Multiple imports should not be included at single line. Wildcard imports
are discouraged. Wildcard imports where you are importing everything from a module
like import static is highly discouraged. There are further rules
that you should include these modules
from the standard library distribution at the top. Then you
should include any third party libraries and at the end you
should mention the imports which you are using from your own project.
String quotes in Python you can define
string rituals by single quote or double quote both. What is recommended
whether we use single quote or double quote, you can use any of them single
or double, but it is recommended that whatever you choose, you should
be consistent throughout your code base. All your programmers should be
aware that you should only use single quote or
double quote to define string literals anywhere in your project.
Another aspect of style guidelines
I would like to cover here is naming conventions for
different constructs of the language. First of all, packages and modules.
These should be named all lowercase, and you should use
short names. Underscore can be used for readability,
but using the underscore is discouraged. Examples are
like pandas models, iter tools, et cetera.
Then we have classes. For classes we can use passport
case which is in it caps as well. We should not
include the world class while naming any class object.
For example, if you want to define an employee class or
student class, we should only name it as employee or
student, not employee class and student class. The class keyword
should not be included in the name of the class. Exception names exceptions
are actually classes in Python, so the name is
same. Naming rules applies, but using suffix error
is recommended to make it explicit that this class is of
exception like limit not expired error type error name
error, et cetera. So error suffix readily tells
you that this class is handling some kind of exception.
It is not a regular class. Constants for this use all
k apps snake case for example, database underscore URL,
API key or base underscore URL.
Like any other programming languages, constants are recommended
to use all caps, nakes, functions, and variables.
These can use standard snake case for example, all lower
better, and you can use underscores to separate out the
words in the names to make them more readable.
For example, def final underscore score team
underscore score like this function or
method arguments. Now the arguments which are being passed to the
functions or class methods. Those follow
the same naming rules as the variables, but if you are writing
an instance method, then its first argument should be self.
If you are defining a class method, then its first argument should be CLS,
that is class. And if you have clash
with any of the keywords of the language, then you can use a trailing underscore
to avoid this clash. For example, if you have a class in which
you have an attribute which is named class, you should use
it as class underscore instead of like misspelling it
clss or clas. This is not recommended.
Methods and instance variables for methods instance variables,
same naming rules applies as of functions, but to segregate
public and non public instance variables and methods,
one leading underscore is used for non public and to avoid parent
child clashes, we can use two leading underscore if we have same
name variables and methods in parent and child both.
The next rule I want to talk about is lenters. So before talking
about lenders, I would like to take
another analogy and describe about that.
What is lint? Lint is actually the small particles
which get stuck to our clothes when we wash them in washing
machines. And that really is annoying that your
clothes are instead of getting cleaned, they actually
get dirty with those small particles stuck
to them for their solution. For the solution of this problem,
all the washing machines in our houses, we have lint filters
installed which collect all these small particles, and your clothes come
out neat and clean as required.
So linter is basically a tool which
collects the small particles or small defects or small
unwanted things from your code base to make
it more readable, more maintainable, and more extendable.
In programming languages or in programming projects,
we have two kinds of lint. One is logical lint.
It includes code errors, dangerous code patterns,
and code with potentially unintended results. Other type of
lint is stylistic lint. This involves around code
not conforming to conventions and style guides.
So for making sure that these
two kinds of lints are not present in your code basis, there are
certain linters available in the Python ecosystem. Some are
implicit and some are explicit. The linters
of Python while writing or creating our projects,
we all use certain ide for developing the Python projects. So ides
are also a kind of linter which includes
implicit filters or implicit linters to make sure that you are adhering
to some basic set of guidelines adopted by the language.
But these linters are basically mostly of stylistic
type. Another example is pilot. This module is a
linter which catches logical and stylistic errors.
Then we have code style. This is purely stylistic, and it
purely follows the pep eight guidelines. Then we have py doc style
to make sure it is also stylistic and it follows the guidelines
mentioned in pep two five seven and it purely checks only
for the comments and doc strings in your code. Then we have PI
flakes. This is purely logic. So how to use these
linters? Ides have implicit id linters.
You don't have to do anything, but all other linters you can
quickly install them through pip install command and then
you can write the command module name pylint and the file name.
Press enter and you will have the list of errors and warnings
which you should be looking at to make your python code more
readable and more maintainable. The next question which
comes to our mind that when to check or when to apply the linters to
our code basis. So for first choices as you write it,
you have written a small piece of code, a small function, a small code snippet.
Just apply the linter, get the stuff done and
you can get the errors corrected and you are done.
The other option is when it's checked into the version
control system. Usually developers check in their codes
at the end of the day. So it is a nice idea to spare
half an hour at the end of the day to apply the linters and make
sure that the errors voted by the linter are resolved. And then you just check
in the code to the version control system. The last option is when running
your tests. This option is viable because you don't
have to apply the linters every day or multiple times in
a day. You will be just applying the linters by only
twice or twice during the sprint cycles,
but this will result in more effort
in resolving the errors reported by these lenders. So in my opinion,
the best choice is to use the option of when
it's checked in. At the end of the day, when you are checking in your
code, apply the linter, fix these errors, and get
these desired code quality with minimum
effort. Now I would like to talk about idiomatic Python.
Before talking about idiomatic Python, let's see that.
What do we mean by the idioms? An idiom is a phrase
that doesn't make literal sense, but makes sense once you are acquainted
with the culture in which it arose. So it doesn't have any literal meaning,
it just acquires the meaning from its surroundings or the culture it is being used
in. Similarly, for programming, an idiom is
a thing you do daily for development in a particular language that are familiar
and meaningful to those who work in these same language. So basically,
idioms are certain language constructs, language features,
or language rules which all the programmers working in
that language follow to make sure that everyone is on
the same page. Now let's look at some common Python
idioms. First of all, swap variables without using temp variables
if you remember your college days when we used to program in c plus
plus to swap the values of two variables,
we'll define a temp variable, assign the first variable to it, and assign
the second variable to first variable, and then the temp variable to the second
variable. So one, two, and three lines of code just to swap
the values of the two variables. But in Python you can do
it simple in one line of code just by swapping
the order of the variables at both sides
of the assignment operator. Do not compare directly to singletons like
true, false, none, or zero. These are actually boolean literals,
so you don't have to check them with the equality sign. The known
idiomatic code will be checking these literals as if foo equal
to equal to true, but the idiomatic python will be checking it like
true or false as it is if foo is none.
So this is the idiomatic way. Use is not instead of
not is not is actually not intuitive and
also confusing. If you are checking for negation,
then you should be using is not operator instead of not
is. The non idiomatic way is if not, foo is
none. So this is not making sense. But the idiomatic way
is if foo is not none. This is easy to understand. This is plain English
and completely readable to anybody. Empty sequences are
also false. This includes empty list, empty dictionary, or empty tuples.
So these empty sequences also behave like just
false Boolean literal, and you can check them in your code.
As we treat the Boolean literals like if empty
list, empty square brackets, repeating variable name and if
statement. So let's take an example in non
idiomatic way. We have a name Tom, and we want to check that
if it is a generic name or not, or more commonly used name or not,
then we will be checking if name equal to tom or name equal
to dick or name equal to Harry. If it is one of them, then set
these is generic name to be true. But what is the idiomatic
way? Idiomatic way is to use the in operator.
The name we want to check is Tom and we have a flag is generic
name. We are checking it with the assignment operator. Name in
true or false is returned through
this in operator, and that is getting assigned to is generic name.
So 1234 lines of code is collapsed two
two lines of code only for loops in other
programming languages, a typical way to write a for loop is define
a variable, set it to zero, check for the container length
and increment it in every iteration and in the curly brackets.
Do whatever you want to do. In Python.
You can achieve the same functionality by this code snippet
for I in range length of my underscore list. Range function
will be starting from zero to length and increment
by one in every iteration. But what is
the idiomatic way? The idiomatic way is to use the python
in operator. That is for element in my underscore
list and you are done. You don't have to worry about these maintaining
the loop counter by yourself looping
backwards again. In other programming languages, you will be
starting the loop counter from the length and decrementing
it in every iteration until you reach the zero. In Python,
you can achieve this through this code snippet. Again, the range function.
You will be starting with the length of list and writting
the step to minus one for every iteration. What is
the idiomatic way? The idiomatic way is to use reversed
for element in reversed my underscore list. This is more efficient
and more readable. Any layman can understand
that we are traversing the list in the reverse order
tracking index of for loop. What is the non idiomatic way?
You will define a counter, set it to zero, and in each iteration
you will be incrementing it one as you go through these list of elements.
What is the idiomatic way? Use enumerate by enumerate
you will get the index and element every time you
read an element from the container list using
for else syntax. This is actually a very interesting Python idiom
and I got to know about it very late.
But these it is. Let's take an example that
we have certain users and we want to check that whether any
user has entered his address or not. So we write
this code snippet. We define a flag, traverse over the
users, check if the user has entered the address. We set the flag
to true and break the loop because we have found that at least
one user has entered the address and at the end of
the code we check for the flag to get to know that whether address was
entered or not. So what is the idiomatic way? The idiomatic way
is to use else clause for the for loop. Yes.
Here is the code snippet. For each user we are checking that whether the
user has entered the address if it has entered the address, we are printing
our message and we are breaking out of the loop. But if the
loop terminates by executing all its iterations and
we have not found any address. Then we are coming to the else clause.
So else clause is executed whenever the loop terminates by
completing all its iterations. Otherwise we will be breaking in
when we found the address using iter to
check for sentinel value. So let's take an example. Over here we
have a file which we want to read in chunks of 32 bytes.
For that we are writing this code snippet. We have
a list, and while we are not reaching
the end of the file, we have not the empty chunk.
We are reading 32 bytes in every iteration
and appending it to list. What is the better way?
The better way is to use the iter function.
Again, we have defined a list in which we will be appending our chunks
of 32 bytes, but we will be using the iter function
in which we can give the sentinel value. Yes, the iter
function can iterate over the list of elements and
also can check for the sentinel value. Two break out of the iterations.
It is better because it is more efficient. And yes,
the first argument of the iter function is a function
with no arguments for that. We are using the partial function which
can reduce any function to zero. Arguments strings
while using strings, we should use string method instead of the
string module because they are fast and more efficient.
We should use dot starts with and dot ends with
instead of slicing for prefix or suffix checking.
Why? Because slicing is more error prone
and using starts with the ends with is less prone to errors.
We should be using dot join while creating strings from list elements instead
of using the plus operator. Yes, the non idiomatic way is to
use for loop and a plus equal operator to
every time concatenate the element two the string. But the
idiomatic way is just to use the join method by
passing the argument of the list to be concatenated
context manager. These are the beautiful python language
constructs. These are the objects to be used with the with statement, and these
objects make resource management more explicit and safer.
It separates business logic from administrative logic and
make the writing business logic made more easy.
Let's take an example. We want to read a file. For that we
have to open the file. Then we'll read the file and these we have to
explicitly close the file. But with the help of context managers
you will not be bothering about closing the file explicitly use
the with open context manager read the file
and you are done. The with context manager automatically closes
the file when you are done reading the file. Let's look at some of the
other examples of context managers. Another example
is, while we are using threading, for using
threads we have to acquire log first log equal to threading
log acquire, and then we execute a critical
section. And in the finally block we have to explicitly
release the lock. But with the context managers the better because
you don't have to explicitly release the lock because if you forget
to release the lock, you will be in a great mess. So with idiomatic Python
or Python language constructs of context managers,
you will just be acquiring the clock lock, and with lock context
manager you will read the execute the recurring section and
you are done. As you will be getting out of the context
manager block, it will automatically release the log for you.
Another example is you
want to remove a certain file from your system,
but what if that file doesn't exist? Your code will error
out. So for that you will have to use the try accept block and
cache the OS error. Whether you want to do something with it or not,
it's up to you. But what is the better way? The better way is to
use the ignored context manager with ignored
and you specify the OS error and remove the
file from your computer. Yes, we are not ignoring the errors,
we are capturing the error with context manager with ignored
and we are specifying that it is an OS error. Yes, we are
passing it silently, implicitly silencing
it. Other examples of context manager includes changing the
standard output to a file instead of computer screens or
monitors or lcds. For this you can use redirect
sd out context manager. You will specify the file, and once
you are done writing to the file, it will automatically shift back
to the standard output of your computer. Another example
is modifying some variable in temporary context. For that
you will be using the local context context manager,
and when you are done working in a temporary context, the context
manager will shift back two the original context you
were working in. Lists are an important data structure in Python
language, so a lot of Python idioms are around
these data structure. Let's talk about some of them. Creating a
length and list of the same thing. How can you do this?
One way to do this is by implementing a for loop.
But in idiomatic python you can use the Python list
static operator to create simple and nested lists
of the same value. Let's look at the code snippet.
Yes, you want to have a list of length five with
every element set to hello. You can just write list equal to
square brackets hello static five, and you can also create nested lists
in the same fashion. List unpacking this is also a
beautiful construct. You also use the static
operator to represent the rest of the list instead of slicing because we have discussed
earlier that slicing is more error prone. It is also a very
nice and beautiful construct of the language,
but in managing the indexes is really
error prone and it is also less readable. The future
programmers working on your code will not be
able to understand that, why you are chunking out certain amount
of data and what it is being used for. So what
is the non edomatic way? You have a list abcde.
You are only interested in first and second element and you're
not interested in the rest of the list. So you'll assign some
underscore list of zero index element to the first variable,
second index variable element to the
second variable, and the rest of the list two the rest variable through
specifying the slicing index two columns. Similarly,
you can be interested in the first and last only, and you
are not interested in the middle of the list, and then you are interested
in the middle element only and not in the head
part or the last part. So this was a non idiomatic way.
What is the idiomatic way? Idiomatic way is to use the static operator.
Through static operator you will specify the variables which you want to
extract and a garbage variable with static
assigned to it. And on the right hand side of the assignment operator
you will just write down the name of the list from which you want to
extract these elements. So 1st 2nd static rest equals to
some underscore list. The other two options can be
followed out as above. Another option is using underscore
as placeholder or throwaway variable. If you don't want to use
any part of the list in the future, you can just replace the variable name
with the underscore and that will not be accessible for future users.
List comprehensions List comprehensions provides a
concise and easy way to create transform and filter lists.
These consist of brackets containing an expression followed by for
and a conditional if clause. For and
if clauses can change places. This means that you
can write for first and then the condition, or you
can write the condition first and then the iterator. It always returns
result as a new list and the actual list is not modified.
So the basic syntax according to these above rules is
like expressions which we need to apply to every element of the list.
Then we have an iterator, then we have a conditional. Another option
is to switch these conditionals and iterator. Let's look
at some of the examples. Double the value of each element in a list.
What is the non idiomatic way you will write a for loop
and for each item you will multiplying it by two. In this case
you will be modifying the actual list and doubling the elements in the
actual list. The idiomatic way is to use the list comprehension.
We have a list. This is the expression x. Direct two is the impression
for x. In ARR, this is the iterator and here
we don't have any condition so this is more concise and beautiful way
to create list. And a new list is being created and signed
to ar. The actual list is not being changed.
Another example, double the value for every even element in a
list. So these non idiomatic way is again write a loop,
check for every item that it is even or not and multiply the
item by two if it is even. In this case we are again
changing these actual list. We are dealing with
what is the idiomatic way using the list comprehension x static
two is the expression we need to apply to
every element that is even. Then we have a conditional if x mod
two equal to equal to zero, then multiply it by two else keep
it as it is for every element in array and do this for every element
in array. This is the iterator and a new list is being assigned to ARR
generator expressions. All list comprehensions can be transformed
into generator expressions, but how?
Remove the square brackets, replace them with the parentheses,
and you are done. Why we should be using generator expressions
because these are more efficient in terms of performance
compute and in terms of memory. Use the
list comprehension creates the whole list from scratch. A new
list is being created and assigned to the and is returned.
But generator expression only evaluates the value which is
required and it does not consume up the
space for creating the new list. It is better and
a lot more faster. Updating lists let's say
you have a code base where you are using lists and you are mostly
interested in the first elements of these list. So you will be deleting
the first element, you will be popping out the first element and you
will be inserting new elements at the start of the list only.
If you are doing this with the list then your code will be damn slow.
So what is the better way to do this? The better way to do this
is to use the tech data structure DQ data
structure. By this you will be deleting the first element
by Dell command. Then you will be using the pop left to
pop the first element and append left two append elements at the
start of the list. But this will be a lot more faster. So wherever
in your code bases. You have these kind of statements,
go find them and replace them with the deck data structure and
pop left independent commands. Dictionaries dictionaries
are also an important data structures in Python, and for
these we have some common idioms. First of
all, we should use dict get method while retrieving values
from the dictionary to specify a default parameter
for default value if a value is not found. So let's
look at the example, the non idiomatic way. We are checking for the debug
levels in our code and what action is to be taken against a
certain debug level. So we'll define the debug level equal to none,
and we'll be finding out that if the critical level is found,
then what action is to be taken. So if debug
level is not found in the dictionary, then we'll be assigning the
default value of info. What is the idiomatic way to
do this? Idiomatic way to do this is using the get
method. It's specifying the default value info
if the required value is not found in the dictionary if
the required key is not found in the dictionary. Actually,
what are the use cases for this method?
Counting with dictionaries let's say we have a dictionary.
We have a list, colors in which we have red,
green, blue, and we want to count the instances of each
color name. We'll define a dictionary, traverse through the colors
if a color is not in the dictionary, we'll be creating
the key and assign a zero to it and increment it by one
every time we find the same color. So the output will be blue two green
two red three. So what is the idiomatic way? Idiomatic way
is to define a dictionary and traverse over the colors for color and
color, and use the get method by specifying the zero
value if key is not found, and increment it if the
key is found every time of the same color. Another way
to do this is using the collections module. From collections we
can use a default dict data structure. Through this data
structure you can define a dictionary of certain type
and it will assign value to all the defined keys to be
an integer. If we are using integer, it will initialize it to
zero. So you will be declaring the default dict of int type,
and we'll be just traversing over the list for color and colors and incrementing
the values if a certain key color is found.
So for dictionaries like list,
we also have dictionary comprehensions to build
dictionaries more efficiently and beautifully.
Examples are again, we have some users and
some have added the address. Some have not added the address. We want
to add users which have added the address to the dictionary.
So we'll be writing the loop and checking for the address entered.
If they have these, we will be creating a key with the username and
assigning it the value of address. What is the idiomatic
way? Idiomatic way is to use the Dict comprehension. For dict comprehension
we use the curly brackets. User name is the key,
users address is its value and this is these iterator for
user and users and this is the condition if user address
looping over dictionary keys how you can loop over the dictionary
keys simple for k indent k. Another way
to do this is for k inde keys print k and
maybe delete some keys or some values. So which one is
better and why? Yes, using the keys method
is better because it is more efficient. It returns
a whole new list of keys and if you perform some
action on any key in these for loop, the original
dictionary will not get affected. Looping over dictionary keys and
values the simplest way to do this is okay d you have key
and you can assign the value from with d of k. Another way to
do is using the d dictionary items method.
It will return all the key value pairs
and you can use them as you want. The third way to do this
is to use d iteritems. Yes, it will also
return the key value pair and you can do whatever you want with this key
value pair. Which one is the best and why?
D items is better? Yes, it is better
because you can change the keys and values and the original dictionary will
not get affected. But is it best? No, the iteritems method
is the best option because not only you can
modify the dictionary without being original
dictionary getting affected, but also it
is an iterative method, it will not be consuming extra
space. So that is all for Python
common idioms. But these idioms and language
features are there to increase the readability and maintainability of
your code basis. These are not there to impress other developers
or discourage or other developers that
these are not writing pythonic or idiomatic Python.
This is not to shame other developers and these
language constructs and idioms should not be used for
the sake of using them. Remember, if a
problem can be solved through a simple solution,
we should not opt for the complex or complicated solution. These are
powerful constructs and these should be used wherever they are
required only as Spiderman says that with power
comes great responsibility. These are some of the
references and further readings to more get familiar
with the Python idioms happy idiomatic
coding and thank you very much for listening to me.