Install Python on Windows, linux, Ubuntu, Debian, macOS, android, iOS

cos | Python Methods and Functions

First, I'll tell you briefly about installing Python on your computer. Downloads page of the official website for the standard Python distribution ( ) contains installers for Python 3.x and 2.x. At the time of this writing, 32-bit and 64-bit MSI installers are available for Python 3.6.2 and python 2.7.13. Download the appropriate installer.

Open the installer with administrator rights and go through the installation wizard using the recommended options. Install for all users and add the python executable to the system path variable when prompted.

Run python.exe from the command line. A command window will appear with a three-character Python prompt gt (& gt; & gt; & gt;). This confirms the successful installation of Python.

Some operating systems, especially Linux, provide a package manager, which you can run to install Python.

On macOS, the best way to install Python 3 involves installing a package manager called Homebrew.

On mobile operating systems ah, such as Android and iOS, you can install applications that provide a Python programming environment. This can be a great way to practice your coding skills on the go.

In addition, there are several websites that allow you to access the Python interpreter online without installing anything at all on your computer.

 There is a possibility that Python may have been shipped with your operating system and already installed. Even so, the installed version is probably out of date, and in any case it is better to install the latest version.

Now I will show you step by step how to set up a working Python 3 distribution for Windows, macOS, Linux, iOS and Android. So let's get started!

Installing Python on Windows

It is highly unlikely that your Windows system comes with Python already installed. Fortunately, installation doesn't require a lot of skill, just download the Python installer from and run it.

Step 1: Download the Python 3 installer

Open a browser window and go to the Windows downloads page at
Under the heading at the top that says Python Releases for Windows, click on the link for the latest Python 3 &Python 3.xx

Scroll down and select either x86-64 executable installer for 64-bit or Windows x86 executable installer for 32-bit.

For Windows, you can select 32 -bit or 64-bit installer. Here's the difference between them:

If your system has a 32-bit processor, you should choose the 32-bit installer.
On a 64-bit system, any installer will work for most purposes ... The 32-bit version typically uses less memory, but the 64-bit version performs better for compute-intensive applications.

If you're not sure which version to choose, choose the 64-bit version.

Note. Remember, if you make the wrong choice and want to switch to a different version of Python, you can simply uninstall the program and then reinstall by downloading a different installer from

Step 2: Run the installer

Just run it by double clicking on the downloaded file. A dialog should appear that looks something like this:

 python installation

Important note: You must be sure that checked Add Python 3.x to PATH as shown to ensure that the interpreter is placed in your execution path.

Then just click Install Now. That's all there is to it. In a few minutes, you should have a working program.

Windows Subsystem for Linux (WSL)

If you are using Windows 10 Creators or the Anniversary Update, you have another installation option. These versions of Windows 10 include a feature called Windows Subsystem for Linux, which allows you to run a Linux environment directly in Windows without modification and without stressing the virtual machine.

Once you have installed your Linux distribution, you can install Python 3 from a Bash console window, as if you were using this Linux distribution natively.


It is very likely that your Linux distribution already has Python installed, but it probably won't latest version, for example Python 2 instead of version 3.

To find out which version you have, open a terminal window and try the following commands:

 python --version python2 --version python3 --version 

If the version shown is Python 2.xx or a version of Python 3 that is not the most recent, you will need to install the latest version. The procedure will depend on the Linux distribution you are using.

Note that it is often easier to use a tool called pyenv to manage multiple versions of Python on Linux.


The installation instructions may differ depending on the version of your Ubuntu distribution. You can determine your local Ubuntu version by running the following command:

 $ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 16.04.4 LTS Release: 16.04 Codename: xenial 

Depending on the version number you see in the Release section of the console output, follow the instructions below:

  • Ubuntu 17.10, Ubuntu 18.04 (and up) ships with Python 3.6 by default. You should be able to invoke it using the python3 command.
  • Ubuntu 16.10 and 17.04 do not ship with Python 3.6 by default, but they are in the Universe repository. You should be able to install it using the following commands:
 $ sudo apt-get update $ sudo apt-get install python3 .6 

Then you can invoke it with the python3.6 command.

If you are using Ubuntu 14.04 or 16.04, Python 3.6 is not in the Universe repository and you need to get it from the personal package archive (PPA). For example, to install Python from the "deadsnakes" PPA, follow these steps:

 $ sudo add-apt-repository ppa: deadsnakes / ppa $ sudo apt-get update $ sudo apt-get install python3.6 

As above, call the python3.6 command.

Linux Mint

Mint and Ubuntu use the same package management system. You can follow the instructions above for Ubuntu 14.04. The "deadsnakes" PPA works with Mint.


I found sources that indicated that the Ubuntu 16.10 method would work for Debian, but never found a way to get it to work on Debian 9.

One problem with Debian is that it does not install the sudo command by default. To install it, you need to do the following before following the instructions below to compile Python:

 $ su $ apt-get install sudo $ vi / etc / sudoers 

Then open the / etc / sudoers file with the sudo vim command (or your favorite text editor). Add the following line of text to the end of the file, replacing your_username with your username:

 your_username ALL = (ALL) ALL 


I found some instructions on how to get zypper to install the latest version of Python, but they seemed out of date. Couldn't get them to work, so went back to the original code. To do this, you need to install development tools that can be done in YaST (via the menu) or with zypper:

 $ sudu zypper install -t pattern devel_C_C++ 

This step took a while and involved installing 154 packages, but after completing it I was able to build the source code.


The IUS community works great over providing new software versions for "Enterprise Linux" distributions (that is, Red Hat Enterprise and CentOS).

To install, you must first update your system using the yum package manager:

 $ sudo yum update $ sudo yum install yum-utils 

Then you can install the CentOS IUS package:

 $ sudo yum install 

Finally, you can install Python and Pip :

 $ sudo yum install python36u $ sudo yum install python36u-pip 

macOS / Mac OS X

Current versions of macOS (formerly known as "Mac OS X") include Python 2.

The best way to install Python 3 on macOS &this is the Homebrew package manager.

Step 1: Install Homebrew (part 1)

To get started, you must first install Homebrew:

  1. Open your browser and go to When the page finishes loading, select the Homebrew bootstrap code under Install Homebrew.
  2. Then press Cmd + C to copy it to your clipboard. Make sure you write down the entire command line, otherwise the installation will fail.
  3. Now you need to open a window, paste in the Homebrew bootstrap code, and press Enter. The Homebrew installation will begin.

If you are doing this on a fresh install of macOS, you may receive a pop-up warning asking you to install Apple's "Command Line Developer Tools". You will need them to proceed with the installation, so please confirm the dialog by clicking Install.

Step 2: Install Homebrew (part 2)

After completing the developer tools installation from the command lines you can proceed with installing Homebrew and then Python:

  1. Confirm the Software Installed dialog from the Developer Tools Installer.
  2. Back in Terminal, press Enter to continue Homebrew installation.
    Homebrew will ask you for your password to complete the installation. Enter your user account password and press Enter to continue.
  3. Depending on your internet connection, Homebrew will download the necessary files in a few minutes. Once the installation is complete, you will be back at the command prompt in a terminal window.

Step 3: Install Python

Once Homebrew has finished installing, return to your terminal and run the following command :

 $ brew install python3 

Note. When you copy this command, make sure you don't include the $ character at the beginning. This is just an indication that this is a console command.

This will download and install the latest version of Python. After the Homebrew brew install command completes, you should already have Python 3 on your system.

You can verify that everything went right by checking if Python is available from the terminal:

  • Open terminal by running
  • Type pip3 and press Enter.
  • You should see help text from the Python package manager "Pip".
  • If you receive error message when running pip3, follow the installation steps again.

iOS (iPhone / iPad)

Pythonista iOS app &it is a complete Python IDE that you can run on your iPhone or iPad. It is basically a combination of a Python editor, documentation, and interpreter combined into one application.

Pythonista comes with the complete Python 3 Standard Library and even includes complete documentation that can be viewed offline.

To install and configure Pythonista, you need to download it from the iOS App Store here .

Android (phones and tablets)

Pydroid 3 has an interpreter that you can use for REPL sessions, and provides the ability to edit, save and execute Python code:

Pydroid 3 Editor

You can download and install Pydroid 3 from Google Play here . There is a free version as well as a premium paid version that supports code prediction and analysis.

Install Python on Windows, linux, Ubuntu, Debian, macOS, android, iOS: StackOverflow Questions

How do I install pip on macOS or OS X?

I spent most of the day yesterday searching for a clear answer for installing pip (package manager for Python). I can"t find a good solution.

How do I install it?

Cost of len() function

What is the cost of len() function for Python built-ins? (list/tuple/string/dictionary)

How to uninstall Anaconda completely from macOS

How can I completely uninstall Anaconda from MacOS Sierra and revert back to the original Python? I have tried using conda-clean -yes but that doesn"t work. I also remove the stuff in ~/.bash_profile but it still uses the Anaconda python and I can still run the conda command.

Cosine Similarity between 2 Number Lists

I want to calculate the cosine similarity between two lists, let"s say for example list 1 which is dataSetI and list 2 which is dataSetII.

Let"s say dataSetI is [3, 45, 7, 2] and dataSetII is [2, 54, 13, 15]. The length of the lists are always equal. I want to report cosine similarity as a number between 0 and 1.

dataSetI = [3, 45, 7, 2]
dataSetII = [2, 54, 13, 15]

def cosine_similarity(list1, list2):
  # How to?

print(cosine_similarity(dataSetI, dataSetII))

How can I install a previous version of Python 3 in macOS using homebrew?

How can I install a previous version of Python 3 in macOS using brew?

With the command brew install python I got the latest version of Python 3 (currently v3.7.0), but I want the last version of Python 3.6 (currently 3.6.5).

I have read about another package pyenv that can assist in handle different python installation, but this solution is not suitable for me.

Cost of exception handlers in Python

In another question, the accepted answer suggested replacing a (very cheap) if statement in Python code with a try/except block to improve performance.

Coding style issues aside, and assuming that the exception is never triggered, how much difference does it make (performance-wise) to have an exception handler, versus not having one, versus having a compare-to-zero if-statement?

Answer #1

In Python, what is the purpose of __slots__ and what are the cases one should avoid this?


The special attribute __slots__ allows you to explicitly state which instance attributes you expect your object instances to have, with the expected results:

  1. faster attribute access.
  2. space savings in memory.

The space savings is from

  1. Storing value references in slots instead of __dict__.
  2. Denying __dict__ and __weakref__ creation if parent classes deny them and you declare __slots__.

Quick Caveats

Small caveat, you should only declare a particular slot one time in an inheritance tree. For example:

class Base:
    __slots__ = "foo", "bar"

class Right(Base):
    __slots__ = "baz", 

class Wrong(Base):
    __slots__ = "foo", "bar", "baz"        # redundant foo and bar

Python doesn"t object when you get this wrong (it probably should), problems might not otherwise manifest, but your objects will take up more space than they otherwise should. Python 3.8:

>>> from sys import getsizeof
>>> getsizeof(Right()), getsizeof(Wrong())
(56, 72)

This is because the Base"s slot descriptor has a slot separate from the Wrong"s. This shouldn"t usually come up, but it could:

>>> w = Wrong()
>>> = "foo"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: foo

The biggest caveat is for multiple inheritance - multiple "parent classes with nonempty slots" cannot be combined.

To accommodate this restriction, follow best practices: Factor out all but one or all parents" abstraction which their concrete class respectively and your new concrete class collectively will inherit from - giving the abstraction(s) empty slots (just like abstract base classes in the standard library).

See section on multiple inheritance below for an example.


  • To have attributes named in __slots__ to actually be stored in slots instead of a __dict__, a class must inherit from object (automatic in Python 3, but must be explicit in Python 2).

  • To prevent the creation of a __dict__, you must inherit from object and all classes in the inheritance must declare __slots__ and none of them can have a "__dict__" entry.

There are a lot of details if you wish to keep reading.

Why use __slots__: Faster attribute access.

The creator of Python, Guido van Rossum, states that he actually created __slots__ for faster attribute access.

It is trivial to demonstrate measurably significant faster access:

import timeit

class Foo(object): __slots__ = "foo",

class Bar(object): pass

slotted = Foo()
not_slotted = Bar()

def get_set_delete_fn(obj):
    def get_set_delete(): = "foo"
    return get_set_delete


>>> min(timeit.repeat(get_set_delete_fn(slotted)))
>>> min(timeit.repeat(get_set_delete_fn(not_slotted)))

The slotted access is almost 30% faster in Python 3.5 on Ubuntu.

>>> 0.3664822799983085 / 0.2846834529991611

In Python 2 on Windows I have measured it about 15% faster.

Why use __slots__: Memory Savings

Another purpose of __slots__ is to reduce the space in memory that each object instance takes up.

My own contribution to the documentation clearly states the reasons behind this:

The space saved over using __dict__ can be significant.

SQLAlchemy attributes a lot of memory savings to __slots__.

To verify this, using the Anaconda distribution of Python 2.7 on Ubuntu Linux, with guppy.hpy (aka heapy) and sys.getsizeof, the size of a class instance without __slots__ declared, and nothing else, is 64 bytes. That does not include the __dict__. Thank you Python for lazy evaluation again, the __dict__ is apparently not called into existence until it is referenced, but classes without data are usually useless. When called into existence, the __dict__ attribute is a minimum of 280 bytes additionally.

In contrast, a class instance with __slots__ declared to be () (no data) is only 16 bytes, and 56 total bytes with one item in slots, 64 with two.

For 64 bit Python, I illustrate the memory consumption in bytes in Python 2.7 and 3.6, for __slots__ and __dict__ (no slots defined) for each point where the dict grows in 3.6 (except for 0, 1, and 2 attributes):

       Python 2.7             Python 3.6
attrs  __slots__  __dict__*   __slots__  __dict__* | *(no slots defined)
none   16         56 + 272†   16         56 + 112† | †if __dict__ referenced
one    48         56 + 272    48         56 + 112
two    56         56 + 272    56         56 + 112
six    88         56 + 1040   88         56 + 152
11     128        56 + 1040   128        56 + 240
22     216        56 + 3344   216        56 + 408     
43     384        56 + 3344   384        56 + 752

So, in spite of smaller dicts in Python 3, we see how nicely __slots__ scale for instances to save us memory, and that is a major reason you would want to use __slots__.

Just for completeness of my notes, note that there is a one-time cost per slot in the class"s namespace of 64 bytes in Python 2, and 72 bytes in Python 3, because slots use data descriptors like properties, called "members".

<member "foo" of "Foo" objects>
>>> type(
<class "member_descriptor">
>>> getsizeof(

Demonstration of __slots__:

To deny the creation of a __dict__, you must subclass object. Everything subclasses object in Python 3, but in Python 2 you had to be explicit:

class Base(object): 
    __slots__ = ()


>>> b = Base()
>>> b.a = "a"
Traceback (most recent call last):
  File "<pyshell#38>", line 1, in <module>
    b.a = "a"
AttributeError: "Base" object has no attribute "a"

Or subclass another class that defines __slots__

class Child(Base):
    __slots__ = ("a",)

and now:

c = Child()
c.a = "a"


>>> c.b = "b"
Traceback (most recent call last):
  File "<pyshell#42>", line 1, in <module>
    c.b = "b"
AttributeError: "Child" object has no attribute "b"

To allow __dict__ creation while subclassing slotted objects, just add "__dict__" to the __slots__ (note that slots are ordered, and you shouldn"t repeat slots that are already in parent classes):

class SlottedWithDict(Child): 
    __slots__ = ("__dict__", "b")

swd = SlottedWithDict()
swd.a = "a"
swd.b = "b"
swd.c = "c"


>>> swd.__dict__
{"c": "c"}

Or you don"t even need to declare __slots__ in your subclass, and you will still use slots from the parents, but not restrict the creation of a __dict__:

class NoSlots(Child): pass
ns = NoSlots()
ns.a = "a"
ns.b = "b"


>>> ns.__dict__
{"b": "b"}

However, __slots__ may cause problems for multiple inheritance:

class BaseA(object): 
    __slots__ = ("a",)

class BaseB(object): 
    __slots__ = ("b",)

Because creating a child class from parents with both non-empty slots fails:

>>> class Child(BaseA, BaseB): __slots__ = ()
Traceback (most recent call last):
  File "<pyshell#68>", line 1, in <module>
    class Child(BaseA, BaseB): __slots__ = ()
TypeError: Error when calling the metaclass bases
    multiple bases have instance lay-out conflict

If you run into this problem, You could just remove __slots__ from the parents, or if you have control of the parents, give them empty slots, or refactor to abstractions:

from abc import ABC

class AbstractA(ABC):
    __slots__ = ()

class BaseA(AbstractA): 
    __slots__ = ("a",)

class AbstractB(ABC):
    __slots__ = ()

class BaseB(AbstractB): 
    __slots__ = ("b",)

class Child(AbstractA, AbstractB): 
    __slots__ = ("a", "b")

c = Child() # no problem!

Add "__dict__" to __slots__ to get dynamic assignment:

class Foo(object):
    __slots__ = "bar", "baz", "__dict__"

and now:

>>> foo = Foo()
>>> foo.boink = "boink"

So with "__dict__" in slots we lose some of the size benefits with the upside of having dynamic assignment and still having slots for the names we do expect.

When you inherit from an object that isn"t slotted, you get the same sort of semantics when you use __slots__ - names that are in __slots__ point to slotted values, while any other values are put in the instance"s __dict__.

Avoiding __slots__ because you want to be able to add attributes on the fly is actually not a good reason - just add "__dict__" to your __slots__ if this is required.

You can similarly add __weakref__ to __slots__ explicitly if you need that feature.

Set to empty tuple when subclassing a namedtuple:

The namedtuple builtin make immutable instances that are very lightweight (essentially, the size of tuples) but to get the benefits, you need to do it yourself if you subclass them:

from collections import namedtuple
class MyNT(namedtuple("MyNT", "bar baz")):
    """MyNT is an immutable and lightweight object"""
    __slots__ = ()


>>> nt = MyNT("bar", "baz")
>>> nt.baz

And trying to assign an unexpected attribute raises an AttributeError because we have prevented the creation of __dict__:

>>> nt.quux = "quux"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: "MyNT" object has no attribute "quux"

You can allow __dict__ creation by leaving off __slots__ = (), but you can"t use non-empty __slots__ with subtypes of tuple.

Biggest Caveat: Multiple inheritance

Even when non-empty slots are the same for multiple parents, they cannot be used together:

class Foo(object): 
    __slots__ = "foo", "bar"
class Bar(object):
    __slots__ = "foo", "bar" # alas, would work if empty, i.e. ()

>>> class Baz(Foo, Bar): pass
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Error when calling the metaclass bases
    multiple bases have instance lay-out conflict

Using an empty __slots__ in the parent seems to provide the most flexibility, allowing the child to choose to prevent or allow (by adding "__dict__" to get dynamic assignment, see section above) the creation of a __dict__:

class Foo(object): __slots__ = ()
class Bar(object): __slots__ = ()
class Baz(Foo, Bar): __slots__ = ("foo", "bar")
b = Baz(), = "foo", "bar"

You don"t have to have slots - so if you add them, and remove them later, it shouldn"t cause any problems.

Going out on a limb here: If you"re composing mixins or using abstract base classes, which aren"t intended to be instantiated, an empty __slots__ in those parents seems to be the best way to go in terms of flexibility for subclassers.

To demonstrate, first, let"s create a class with code we"d like to use under multiple inheritance

class AbstractBase:
    __slots__ = ()
    def __init__(self, a, b):
        self.a = a
        self.b = b
    def __repr__(self):
        return f"{type(self).__name__}({repr(self.a)}, {repr(self.b)})"

We could use the above directly by inheriting and declaring the expected slots:

class Foo(AbstractBase):
    __slots__ = "a", "b"

But we don"t care about that, that"s trivial single inheritance, we need another class we might also inherit from, maybe with a noisy attribute:

class AbstractBaseC:
    __slots__ = ()
    def c(self):
        print("getting c!")
        return self._c
    def c(self, arg):
        print("setting c!")
        self._c = arg

Now if both bases had nonempty slots, we couldn"t do the below. (In fact, if we wanted, we could have given AbstractBase nonempty slots a and b, and left them out of the below declaration - leaving them in would be wrong):

class Concretion(AbstractBase, AbstractBaseC):
    __slots__ = "a b _c".split()

And now we have functionality from both via multiple inheritance, and can still deny __dict__ and __weakref__ instantiation:

>>> c = Concretion("a", "b")
>>> c.c = c
setting c!
>>> c.c
getting c!
Concretion("a", "b")
>>> c.d = "d"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: "Concretion" object has no attribute "d"

Other cases to avoid slots:

  • Avoid them when you want to perform __class__ assignment with another class that doesn"t have them (and you can"t add them) unless the slot layouts are identical. (I am very interested in learning who is doing this and why.)
  • Avoid them if you want to subclass variable length builtins like long, tuple, or str, and you want to add attributes to them.
  • Avoid them if you insist on providing default values via class attributes for instance variables.

You may be able to tease out further caveats from the rest of the __slots__ documentation (the 3.7 dev docs are the most current), which I have made significant recent contributions to.

Critiques of other answers

The current top answers cite outdated information and are quite hand-wavy and miss the mark in some important ways.

Do not "only use __slots__ when instantiating lots of objects"

I quote:

"You would want to use __slots__ if you are going to instantiate a lot (hundreds, thousands) of objects of the same class."

Abstract Base Classes, for example, from the collections module, are not instantiated, yet __slots__ are declared for them.


If a user wishes to deny __dict__ or __weakref__ creation, those things must not be available in the parent classes.

__slots__ contributes to reusability when creating interfaces or mixins.

It is true that many Python users aren"t writing for reusability, but when you are, having the option to deny unnecessary space usage is valuable.

__slots__ doesn"t break pickling

When pickling a slotted object, you may find it complains with a misleading TypeError:

>>> pickle.loads(pickle.dumps(f))
TypeError: a class that defines __slots__ without defining __getstate__ cannot be pickled

This is actually incorrect. This message comes from the oldest protocol, which is the default. You can select the latest protocol with the -1 argument. In Python 2.7 this would be 2 (which was introduced in 2.3), and in 3.6 it is 4.

>>> pickle.loads(pickle.dumps(f, -1))
<__main__.Foo object at 0x1129C770>

in Python 2.7:

>>> pickle.loads(pickle.dumps(f, 2))
<__main__.Foo object at 0x1129C770>

in Python 3.6

>>> pickle.loads(pickle.dumps(f, 4))
<__main__.Foo object at 0x1129C770>

So I would keep this in mind, as it is a solved problem.

Critique of the (until Oct 2, 2016) accepted answer

The first paragraph is half short explanation, half predictive. Here"s the only part that actually answers the question

The proper use of __slots__ is to save space in objects. Instead of having a dynamic dict that allows adding attributes to objects at anytime, there is a static structure which does not allow additions after creation. This saves the overhead of one dict for every object that uses slots

The second half is wishful thinking, and off the mark:

While this is sometimes a useful optimization, it would be completely unnecessary if the Python interpreter was dynamic enough so that it would only require the dict when there actually were additions to the object.

Python actually does something similar to this, only creating the __dict__ when it is accessed, but creating lots of objects with no data is fairly ridiculous.

The second paragraph oversimplifies and misses actual reasons to avoid __slots__. The below is not a real reason to avoid slots (for actual reasons, see the rest of my answer above.):

They change the behavior of the objects that have slots in a way that can be abused by control freaks and static typing weenies.

It then goes on to discuss other ways of accomplishing that perverse goal with Python, not discussing anything to do with __slots__.

The third paragraph is more wishful thinking. Together it is mostly off-the-mark content that the answerer didn"t even author and contributes to ammunition for critics of the site.

Memory usage evidence

Create some normal objects and slotted objects:

>>> class Foo(object): pass
>>> class Bar(object): __slots__ = ()

Instantiate a million of them:

>>> foos = [Foo() for f in xrange(1000000)]
>>> bars = [Bar() for b in xrange(1000000)]

Inspect with guppy.hpy().heap():

>>> guppy.hpy().heap()
Partition of a set of 2028259 objects. Total size = 99763360 bytes.
 Index  Count   %     Size   % Cumulative  % Kind (class / dict of class)
     0 1000000  49 64000000  64  64000000  64 __main__.Foo
     1     169   0 16281480  16  80281480  80 list
     2 1000000  49 16000000  16  96281480  97 __main__.Bar
     3   12284   1   987472   1  97268952  97 str

Access the regular objects and their __dict__ and inspect again:

>>> for f in foos:
...     f.__dict__
>>> guppy.hpy().heap()
Partition of a set of 3028258 objects. Total size = 379763480 bytes.
 Index  Count   %      Size    % Cumulative  % Kind (class / dict of class)
     0 1000000  33 280000000  74 280000000  74 dict of __main__.Foo
     1 1000000  33  64000000  17 344000000  91 __main__.Foo
     2     169   0  16281480   4 360281480  95 list
     3 1000000  33  16000000   4 376281480  99 __main__.Bar
     4   12284   0    987472   0 377268952  99 str

This is consistent with the history of Python, from Unifying types and classes in Python 2.2

If you subclass a built-in type, extra space is automatically added to the instances to accomodate __dict__ and __weakrefs__. (The __dict__ is not initialized until you use it though, so you shouldn"t worry about the space occupied by an empty dictionary for each instance you create.) If you don"t need this extra space, you can add the phrase "__slots__ = []" to your class.

Answer #2

pip show <package name> will provide the location for Windows and macOS, and I"m guessing any system. :)

For example:

> pip show cvxopt
Name: cvxopt
Version: 1.2.0
Location: /usr/local/lib/python2.7/site-packages

Answer #3

Because [] and {} are literal syntax. Python can create bytecode just to create the list or dictionary objects:

>>> import dis
>>> dis.dis(compile("[]", "", "eval"))
  1           0 BUILD_LIST               0
              3 RETURN_VALUE        
>>> dis.dis(compile("{}", "", "eval"))
  1           0 BUILD_MAP                0
              3 RETURN_VALUE        

list() and dict() are separate objects. Their names need to be resolved, the stack has to be involved to push the arguments, the frame has to be stored to retrieve later, and a call has to be made. That all takes more time.

For the empty case, that means you have at the very least a LOAD_NAME (which has to search through the global namespace as well as the builtins module) followed by a CALL_FUNCTION, which has to preserve the current frame:

>>> dis.dis(compile("list()", "", "eval"))
  1           0 LOAD_NAME                0 (list)
              3 CALL_FUNCTION            0
              6 RETURN_VALUE        
>>> dis.dis(compile("dict()", "", "eval"))
  1           0 LOAD_NAME                0 (dict)
              3 CALL_FUNCTION            0
              6 RETURN_VALUE        

You can time the name lookup separately with timeit:

>>> import timeit
>>> timeit.timeit("list", number=10**7)
>>> timeit.timeit("dict", number=10**7)

The time discrepancy there is probably a dictionary hash collision. Subtract those times from the times for calling those objects, and compare the result against the times for using literals:

>>> timeit.timeit("[]", number=10**7)
>>> timeit.timeit("{}", number=10**7)
>>> timeit.timeit("list()", number=10**7)
>>> timeit.timeit("dict()", number=10**7)

So having to call the object takes an additional 1.00 - 0.31 - 0.30 == 0.39 seconds per 10 million calls.

You can avoid the global lookup cost by aliasing the global names as locals (using a timeit setup, everything you bind to a name is a local):

>>> timeit.timeit("_list", "_list = list", number=10**7)
>>> timeit.timeit("_dict", "_dict = dict", number=10**7)
>>> timeit.timeit("_list()", "_list = list", number=10**7)
>>> timeit.timeit("_dict()", "_dict = dict", number=10**7)

but you never can overcome that CALL_FUNCTION cost.

Answer #4

Once upon a time I stumbled with this issue. If you"re using macOS go to Macintosh HD > Applications > Python3.6 folder (or whatever version of python you"re using) > double click on "Install Certificates.command" file. :D

Answer #5

⚡️ TL;DR — One line solution.

All you have to do is:

sudo easy_install pip

2019: ⚠️easy_install has been deprecated. Check Method #2 below for preferred installation!


⚡️ OK, I read the solutions given above, but here"s an EASY solution to install pip.

MacOS comes with Python installed. But to make sure that you have Python installed open the terminal and run the following command.

python --version

If this command returns a version number that means Python exists. Which also means that you already have access to easy_install considering you are using macOS/OSX.

ℹ️ Now, all you have to do is run the following command.

sudo easy_install pip

After that, pip will be installed and you"ll be able to use it for installing other packages.

Let me know if you have any problems installing pip this way.


P.S. I ended up blogging a post about it. QuickTip: How Do I Install pip on macOS or OS X?

✅ UPDATE (Jan 2019): METHOD #2: Two line solution —

easy_install has been deprecated. Please use instead.

First of all download the get-pip file

curl -o

Now run this file to install pip


That should do it.

Another gif you said? Here ya go!

Answer #6

You can"t.

One workaround is to create clone a new environment and then remove the original one.

First, remember to deactivate your current environment. You can do this with the commands:

  • deactivate on Windows or
  • source deactivate on macOS/Linux.


conda create --name new_name --clone old_name
conda remove --name old_name --all # or its alias: `conda env remove --name old_name`

Notice there are several drawbacks of this method:

  1. It redownloads packages (you can use --offline flag to disable it)
  2. Time consumed on copying environment"s files
  3. Temporary double disk usage

There is an open issue requesting this feature.

Answer #7

This isn"t a solution to your specific problem, but I"m putting it here because this thread is the top Google result for "SSL: CERTIFICATE_VERIFY_FAILED", and it lead me on a wild goose chase.

If you have installed Python 3.6 on OSX and are getting the "SSL: CERTIFICATE_VERIFY_FAILED" error when trying to connect to an https:// site, it"s probably because Python 3.6 on OSX has no certificates at all, and can"t validate any SSL connections. This is a change for 3.6 on OSX, and requires a post-install step, which installs the certifi package of certificates. This is documented in the file ReadMe.rtf, which you can find at /Applications/Python 3.6/ReadMe.rtf (see also the file Conclusion.rtf, and the script that generates the macOS installer).

The ReadMe will have you run the post-install script at /Applications/Python 3.6/Install Certificates.command (its source is install_certificates.command), which:

Release notes have some more info:

On newer versions of Python, there is more documentation about this:

Answer #8

Per the original docs:

Choose Anaconda if you:

  • Are new to conda or Python
  • Like the convenience of having Python and over 1500 scientific packages automatically installed at once
  • Have the time and disk space (a few minutes and 3 GB), and/or
  • Don‚Äôt want to install each of the packages you want to use individually.

Choose Miniconda if you:

  • Do not mind installing each of the packages you want to use individually.
  • Do not have time or disk space to install over 1500 packages at once, and/or
  • Just want fast access to Python and the conda commands, and wish to sort out the other programs later.

I use Miniconda myself. Anaconda is bloated. Many of the packages are never used and could still be easily installed if and when needed.

Note that Conda is the package manager (e.g. conda list displays all installed packages in the environment), whereas Anaconda and Miniconda are distributions. A software distribution is a collection of packages, pre-built and pre-configured, that can be installed and used on a system. A package manager is a tool that automates the process of installing, updating, and removing packages.

Anaconda is a full distribution of the central software in the PyData ecosystem, and includes Python itself along with the binaries for several hundred third-party open-source projects. Miniconda is essentially an installer for an empty conda environment, containing only Conda, its dependencies, and Python. Source.

Once Conda is installed, you can then install whatever package you need from scratch along with any desired version of Python.

2- is the version number for your Anaconda installation package. Strangely, it is not listed in their Old Package Lists.

In April 2016, the Anaconda versioning jumped from 2.5 to 4.0 in order to avoid confusion with Python versions 2 & 3. Version 4.0 included the Anaconda Navigator.

Release notes for subsequent versions can be found here.

Answer #9

Python >= 3.5 alternative: unpack into a list literal [*newdict]

New unpacking generalizations (PEP 448) were introduced with Python 3.5 allowing you to now easily do:

>>> newdict = {1:0, 2:0, 3:0}
>>> [*newdict]
[1, 2, 3]

Unpacking with * works with any object that is iterable and, since dictionaries return their keys when iterated through, you can easily create a list by using it within a list literal.

Adding .keys() i.e [*newdict.keys()] might help in making your intent a bit more explicit though it will cost you a function look-up and invocation. (which, in all honesty, isn"t something you should really be worried about).

The *iterable syntax is similar to doing list(iterable) and its behaviour was initially documented in the Calls section of the Python Reference manual. With PEP 448 the restriction on where *iterable could appear was loosened allowing it to also be placed in list, set and tuple literals, the reference manual on Expression lists was also updated to state this.

Though equivalent to list(newdict) with the difference that it"s faster (at least for small dictionaries) because no function call is actually performed:

%timeit [*newdict]
1000000 loops, best of 3: 249 ns per loop

%timeit list(newdict)
1000000 loops, best of 3: 508 ns per loop

%timeit [k for k in newdict]
1000000 loops, best of 3: 574 ns per loop

with larger dictionaries the speed is pretty much the same (the overhead of iterating through a large collection trumps the small cost of a function call).

In a similar fashion, you can create tuples and sets of dictionary keys:

>>> *newdict,
(1, 2, 3)
>>> {*newdict}
{1, 2, 3}

beware of the trailing comma in the tuple case!

Answer #10

I think you"re almost there, try removing the extra square brackets around the lst"s (Also you don"t need to specify the column names when you"re creating a dataframe from a dict like this):

import pandas as pd
lst1 = range(100)
lst2 = range(100)
lst3 = range(100)
percentile_list = pd.DataFrame(
    {"lst1Title": lst1,
     "lst2Title": lst2,
     "lst3Title": lst3

    lst1Title  lst2Title  lst3Title
0          0         0         0
1          1         1         1
2          2         2         2
3          3         3         3
4          4         4         4
5          5         5         5
6          6         6         6

If you need a more performant solution you can use np.column_stack rather than zip as in your first attempt, this has around a 2x speedup on the example here, however comes at bit of a cost of readability in my opinion:

import numpy as np
percentile_list = pd.DataFrame(np.column_stack([lst1, lst2, lst3]), 
                               columns=["lst1Title", "lst2Title", "lst3Title"])

Get Solution for free from DataCamp guru