Python Functions vs. Perl Functions

News Python -- Scripting language with generators and coroutines

Python for Perl programmers

Recommended Links Perl to Python functions map Execution of commands and shell scripts using subprocess module Two-pass "fuzzy" compiler from Perl to Python
Chomp to string.rstrip Perl and Python string functions mapping Perl special variable mapping to Python Execution of commands and shell scripts using subprocess module Command-Line Syntax and Options Imitation of Perl double quoted strings in Python Chomp to string.rstrip
Python ternary conditional operator Imitation of Perl double quoted strings in Python Loops in Python Loop else Execution of commands and capturing output of shell scripts and pipelines  Comparison of Perl and Python string operations Functions
Python source code checking tools to help you find common bugs Python pretty printers          
Python Debugging pdb — The Python Debugger Python Braces Debate Programming environment Python IDEs Pycharm IDE Jython
Debugging in Python Algorithms Quotes Python history Python Cheatsheets Etc Tutorials

Most statements in a typical Python program are part of functions. In Python the execution of the  code in a function body may be faster than at a module’s top level so in Python statement in main body serve just for invocation of the function main.  Which has an advantage in clarity and readability as in main body the nesting level is zero and each statement should start with position 1.

Like Perl, in addition to user defined function,  Python provides many built-in functions. A request to execute a function is known as a function call. When you call a function, you can pass arguments that specify data upon which the function performs its computation. In Python, a function always returns a result value, either None  or a value that represents the results of the computation.

Functions defined within class  statements are also known as methods; the general coverage of functions in this section, however, also applies to methods.

In Python, functions are first class objects and can be assigned to variables, passed as parameters, etc. 

A function call is an expression with the following syntax:

function_name(arguments)

When the function call executes, the parameters defines in function definition are bound to the argument values, the function body executes, and the value of the function-call expression is whatever the function returns. Arguments is a list of  expressions are known as positional arguments. Each positional argument supplies the value for the parameter that mapped to corresponding parameter in the function definition. By default the number  of positional arguments should match the number of poistionsl positional parameters. But Python functions can be defined in a way that there the number of parameters is flexible —if there are more positional arguments that positional parameters, the additional arguments are bound to so called named parameters. If not default values for those parameters are used.

The return  statement in Python can exist only inside a function body, and can optionally be followed by an expression. When return  executes, the function terminates, and the value of the expression is the function’s result.

A function returns None  if it terminates by reaching the end of its body or by executing a return  statement that has no expression

The def Statement

The def  statement in Python is similar to sub statement in Perl and allow to a user to define  a function. Unlike Perl were parameters are elements of the array @ Python allow explicit specification of the parameters passed to function (but not their type -- lazy typing is in place).

Unlike Perl, by default functions in Python have fixed number of arguments. The syntax is simple:

def function_name(parameters ): statement(s)

function_name  is an identifier -- much like in Perl. 

parameters  (or more precisely forma parameters)  an optional list of identifiers that get bound to the values supplied when you call the function. Here we need to distinguish between parameter -- variable named used in function and arguments -- variables names passed to function on invocation of the function. All of them can recieve new names in function body

If no parameters is passed the function definition should have has empty round parentheses pair after function_name, and in all calls to the function.

When a function does accept arguments, parameters  contains one or more identifiers, separated by commas (,). In this case, each call to the function supplies values, known as arguments, corresponding to the parameters listed in the function definition. The parameters are local variables of the function (as we’ll discuss later in this section), and each call to the function binds these local variables in the function namespace to the corresponding values that the caller, or the function definition, supplies as arguments.

The nonempty block of statements, known as the function body, does not execute when the def  statement executes. Rather, the function body executes later, each time you call the function. The function body can contain zero or more occurrences of the return  statement, as we’ll discuss shortly.

Here’s an example of a simple function that returns a value that is twice the value passed to it each time it’s called:

def twice(x):
    return x*2

Note that the argument can be anything that can be multiplied by two, so the function could be called with a number, string, list, or tuple as an argument, and it would return, in each case, a new value of the same type as the argument.

 Parameters

Parameters (more pedantically, formal parameters) name, and sometimes specify a default value for, the values passed into a function call. Each of the names is bound inside a new local namespace -- the namespace of this function. 

In Python, in the comma-separated list of parameters, zero or more positional parameters may be followed by zero or more named parameters (optional parameters)  with the syntax:

identifier=default_expression

When a function call does not supply an argument corresponding to a named parameter, the default value is assumed.

The default value in this expression is computed only once, when the def  statement evaluates. But if the default expression is a mutable varible or list it can be changes if particular variable changes. Usually this is not the behavior you want

Also in Python, at the end of the parameter list you may optionally use one or both of the special keywords *args  and **kwargs. The names are arbitrary *k, **m is OK)

The number of parameters of a function, together with the parameters’ names, the number of mandatory parameters, and the information on whether (at the end of the parameters) either or both of the single- and double-asterisk special forms are present, collectively form a specification known as the function’s signature. A function’s signature defines the ways in which you can call the function.

NOTE: In Python3 only, a def  statement also optionally lets you specify parameters that must, when you call the function, correspond to named arguments of the form identifier=expression   If these parameters appear, they must come after *args (if any) and before **kwargs  (if any) and have no analog in Perl.

Python function attributes

The def  statement sets some attributes of a function object. Attribute __name__  refers to the identifier string given as the function name in the def. You may rebind the attribute to any string value, but trying to unbind it raises an exception. Attribute __defaults__, which you may freely rebind or unbind, refers to the tuple of default values for optional parameters (an empty tuple, if the function has no optional parameters).

Unlike Perl in Python, there is another function attribute called the documentation string, or the docstring. You may use or rebind a function’s docstring attribute as __doc__. If the first statement in the function body is a string literal, the compiler binds that string as the function’s docstring attribute. For example:

def sum_args(*numbers):
    """Return the sum of multiple numerical arguments.

  The arguments are zero or more numbers. 
 The result is their sum.
 """
    return sum(numbers)

It is an element of good Python style to provide the docstring for each function. In Perl similar purpose serves the comment between sub statement and opening bracket but using them is just a good practice and you can't retrieve the value of docsting in the body of the unction. But those comments that  exits between  sub and opening { can be converted to Python docstring automatically, though. 

There are two simple conventions which make docstring similar in structure to email message.

In addition to its predefined attributes, a function object may have user defined attributes. To create an attribute of a function object, bind a value to the appropriate attribute reference in an assignment statement after the def  statement executes. For example, a function could count how many times it gets called:

def counter():
    counter.count += 1
    return counter.count
counter.count = 0

 

Function namespace

Perl allow to provide local to the function variable with my declaration. In Python there is no direct analog to my and more complex rules are used.

You can explicitly declare variables that belong to the module namespace in the function by using the keyword global  That covers Perl own and state variable

Emulation of Perl local variables (my variables) can be  done  by first assigning the variable the value None as a kind of pesudo declaration. 

By default, any variable that is bound within a function body is a local variable of the function. If a function needs to bind or rebind some global variables (not a good practice!), the first statement of the function’s body must be:

global identifiers

where identifiers  is one or more identifiers separated by commas (,). The identifiers listed in a global  statement refer to the global variables (i.e., attributes of the module object) that the function needs to bind or rebind. For example, the function counter  that we saw in “Other attributes of function objects” could be implemented using global  and a global variable, rather than an attribute of the function object:

_count = 0
def counter():
    global _count
     _count += 1
    return _count

Without the global  statement, the counter  function would raise an UnboundLocalError  exception because _count  would then be an uninitialized (unbound) local variable. While the global  statement enables this kind of programming, this style is inelegant and unadvisable. 

 

Nested functions and nested scopes

A def  statement within a function body defines a nested function, and the function whose body includes the def  is known as an outer function to the nested one. Code in a nested function’s body may access (but not rebind) local variables of an outer function, also known as free variables of the nested function.

The simplest way to let a nested function access a value is often not to rely on nested scopes, but rather to pass that value explicitly as one of the function’s arguments. If necessary, the argument’s value can be bound at nested function def  time, by using the value as the default for an optional argument. For example:

def percent1(a, b, c):
    def pc(x, total=a+b+c):
        return (x*100.0) / total
     print('Percentages are:', pc(a), pc(b), pc(c))

Here’s the same functionality using nested scopes:

def percent2(a, b, c):
    def pc(x):
        return (x*100.0) / (a+b+c)
    print('Percentages are:', pc(a), pc(b), pc(c))

In this specific case, percent1  has at least a tiny advantage: the computation of a+b+c  happens only once, while percent2’s inner function pc  repeats the computation three times. However, when the outer function rebinds local variables between calls to the nested function, repeating the computation can be necessary: be aware of both approaches, and choose the appropriate one case by case.

A nested function that accesses values from outer local variables is also known as a closure. The following example shows how to build a closure:

def make_adder(augend):
    def add(addend):
        return addend+augend
    return add

Closures are sometimes an exception to the general rule that the object-oriented mechanisms covered in Chapter 4 are the best way to bundle together data and code. When you need specifically to construct callable objects, with some parameters fixed at object-construction time, closures can be simpler and more effective than classes. For example, the result of make_adder(7)  is a function that accepts a single argument and adds 7  to that argument. An outer function that returns a closure is a “factory” for members of a family of functions distinguished by some parameters, such as the value of argument augend  in the previous example, and may often help you avoid code duplication.

In v3 only, the nonlocal  keyword acts similarly to global, but it refers to a name in the namespace of some lexically surrounding function. When it occurs in a function definition nested several levels deep, the compiler searches the namespace of the most deeply nested containing function, then the function containing that one, and so on, until the name is found or there are no further containing functions, in which case the compiler raises an error.

Here’s a v3-only nested-functions approach to the “counter” functionality we implemented in previous sections using a function attribute, then a global variable:

def make_counter(): count = 0 def counter(): nonlocal count count += 1 return count return counter c1 = make_counter() c2 = make_counter() print(c1(), c1(), c1()) # prints: 1 2 3 print(c2(), c2()) # prints: 1 2 print(c1(), c2(), c1()) # prints: 4 3 5  

A key advantage of this approach versus the previous ones is that nested functions, just like an OOP approach, let you make independent counters, here c1  and c2—each closure keeps its own state and doesn’t interfere with the other.

This example is v3-only because it requires nonlocal, since the inner function counter  needs to rebind free variable count. In v2, you would need a somewhat nonintuitive trick to achieve the same effect without rebinding a free variable:

def make_counter():
    count = [0]
    def counter():
        count[0] += 1
        return count[0]
    return counter

Clearly, the v3-only version is more readable, since it doesn’t require any trick.

lambda Expressions

If a function body is a single return  expression  statement, you may choose to replace the function with the special lambda  expression form:

lambda parameters: expression

A lambda  expression is the anonymous equivalent of a normal function whose body is a single return  statement. Note that the lambda  syntax does not use the return  keyword. You can use a lambda  expression wherever you could use a reference to a function. lambda  can sometimes be handy when you want to use an extremely simple function as an argument or return value. Here’s an example that uses a lambda  expression as an argument to the built-in filter  function (covered in Table 7-2):

a_list = [1, 2, 3, 4, 5, 6, 7, 8, 9]
low = 3
high = 7
filter(lambda x: low<=x<high, a_list)    # returns: [3, 4, 5, 6]

(In v3, filter  returns an iterator, not a list.) Alternatively, you can always use a local def  statement to give the function object a name, then use this name as an argument or return value. Here’s the same filter  example using a local def  statement:

a_list = [1, 2, 3, 4, 5, 6, 7, 8, 9]
def within_bounds(value, low=3, high=7):
    return low<=value><high
filter(within_bounds, a_list)            # returns: [3, 4, 5, 6]

While lambda  can at times be handy, def  is usually better: it’s more general, and makes the code more readable, as you can choose a clear name for the function.


Top Visited
Switchboard
Latest
Past week
Past month

NEWS CONTENTS

Old News ;-)

[Aug 31, 2020] Ask Question

Jan 01, 2015 | stackoverflow.com

Asked 5 years, 4 months ago Active 1 year, 8 months ago Viewed 90 times

https://tpc.googlesyndication.com/safeframe/1-0-37/html/container.html Report this ad


shaheen gul , 2015-04-18 04:57:10

0

I want to squeez the characters, for this I write the code but my regular expression did not worked python code is:

file1 = open("C:/Python26/Normalized.txt");
normal = re.compile(r'(.)(\1+)')
f1=open("rzlt.txt",'w')
contents1=file1.read();
tokens1 = nltk.word_tokenize(contents1)                    
for t in tokens1:
    t = re.sub(normal,r'\1',t)
    f1.write(t+"\n")
f1.close()

my file is like

AA-0
A-aaaa-aaaaaaaaaaa
aaaaaaaa-aaaaaaaa
aaaaaaaaaaaaa-aaaaaa
AA-aaaaa-A
aaaaa-A-aaaa
AAA-0-aaaa-aaaaaaaa-aaaaaa
AAA-0
AAA-0-aaaaaaaa
AAA-0
aaaaaaaa

Desired output is

A-0
A-a-a
a-a
a-a
A-a-A
......
python regex share improve this question follow edited Dec 8 '18 at 16:16 Cœur 29.5k 15 15 gold badges 163 163 silver badges 212 212 bronze badges asked Apr 18 '15 at 4:57 shaheen gul 1 1 1 bronze badge

Bryan Oakley ,

What's your desired output? – jwilner Apr 18 '15 at 4:58

> ,

1
import re
normal = re.compile(r'(.)(\1+)')
with open("Normalized.txt") as file1:
    with open("rzlt.txt", 'w') as f1:
        for line in file1:
            f1.write(normal.sub(r'\1', line))

This produces the output:

A-0
A-a-a
a-a
a-a
A-a-A
a-A-a
A-0-a-a-a
A-0
A-0-a
A-0
a

[Aug 30, 2020] How to remove punctuation marks from a string in Python 3.x using .translate()?

Jan 01, 2015 | stackoverflow.com

Ask Question Asked 4 years, 8 months ago Active 4 months ago Viewed 93k times

https://tpc.googlesyndication.com/safeframe/1-0-37/html/container.html Report this ad


cybujan , 2015-12-15 16:05:03

75 28

I want to remove all punctuation marks from a text file using .translate() method. It seems to work well under Python 2.x but under Python 3.4 it doesn't seem to do anything.

My code is as follows and the output is the same as input text.

import string
fhand = open("Hemingway.txt")
for fline in fhand:
    fline = fline.rstrip()
    print(fline.translate(string.punctuation))
python python-3.x share improve this question follow edited Aug 22 '17 at 20:28 wkl 64.8k 12 12 gold badges 145 145 silver badges 168 168 bronze badges asked Dec 15 '15 at 16:05 cybujan 917 1 1 gold badge 8 8 silver badges 12 12 bronze badges

> ,

add a comment 5 Answers Active Oldest Votes

wkl , 2015-12-15 16:27:08

170

You have to create a translation table using maketrans that you pass to the str.translate method.

In Python 3.1 and newer, maketrans is now a static-method on the str type , so you can use it to create a translation of each punctuation you want to None .

import string

# Thanks to Martijn Pieters for this improved version

# This uses the 3-argument version of str.maketrans
# with arguments (x, y, z) where 'x' and 'y'
# must be equal-length strings and characters in 'x'
# are replaced by characters in 'y'. 'z'
# is a string (string.punctuation here)
# where each character in the string is mapped
# to None
translator = str.maketrans('', '', string.punctuation)

# This is an alternative that creates a dictionary mapping
# of every character from string.punctuation to None (this will
# also work)
#translator = str.maketrans(dict.fromkeys(string.punctuation))

s = 'string with "punctuation" inside of it! Does this work? I hope so.'

# pass the translator to the string's translate method.
print(s.translate(translator))

This should output:

string with punctuation inside of it Does this work I hope so
share improve this answer follow edited Jan 16 '17 at 19:56 answered Dec 15 '15 at 16:27 wkl 64.8k 12 12 gold badges 145 145 silver badges 168 168 bronze badges

,

This is nicely done. It's unfortunate that the top Google results for this topic are deprecated, slower, or more difficult to follow. – rurp Apr 26 '16 at 5:38

[Aug 09, 2020] Does Python have a defined or operator like Perl- - Stack Overflow

Aug 09, 2020 | stackoverflow.com

Franz Kafka ,

This question already has answers here :

juanpa.arrivillaga ,

the issue isn't or it's that foo['doesntexist'] is raising an error. – juanpa.arrivillaga Mar 4 '17 at 1:08

Francisco Couzo ,

You don't need the or at all:

bar = foo.get('doesntexist', foo['key1'])

> ,

Perfect, thank you! That is exactly what I was looking for. – Franz Kafka Mar 4 '17 at 1:11

> ,

The reason your method is not working is because Python raises an error before your boolean expression is able to be evaluated. Instead of simply indexing the dictionary, you need to use .get() instead. Rather than raising an error, .get() returns None which allows your expression to be evaluated correctly:

bar = foo.get('doesntexist') or foo.get('key1')

Note that if the value of the first key is 0 or any other value that evaluates to false, your method will fail. If this is fine with you than use the method above.

However, if you'd like not to have the behavior described above, you must test if the first value is None . At this point however, it would be better to simply extract this logic to a separate function:

def get_key(d, test_key, default_key):
    """
    Given a dictionary(d), return the value of test_key.
    If test_key does not exists, return the default_key 
    instead.
    """
    if d.get(test_key) is not None:
        return d.get(test_key)
    return d.get(default_key)

Which can be used like so:

foo = {'key1':'val1','key2':'val2'}
bar = get_key(foo, 'doesntexist', 'key1')

[Aug 09, 2020] Python2 Tutorial Passing Arguments

Notable quotes:
"... This means that Python initially behaves like call-by-reference, but as soon as we are changing the value of such a variable, Python "switches" to call-by-value. ..."
Nov 23, 2019 | python-course.eu
Parameter Passing "call by value" and "call by name" The most common evaluation strategy when passing arguments to a function has been call by value and call by reference: In ALGOL 60 and COBOL has been known a different concept, which was called call-by-name, which isn't used anymore in modern languages. and what about Python? There are books which call the strategy of Python call-by-value and others call it call-by-reference. You may ask yourself, what is right. Humpty Dumpty supplies the explanation: Humpty Dumpty supplies the explanation: Humpty Dumpty supplies the explanation: --- "When I use a word," Humpty Dumpty said, in a rather a scornful tone, "it means just what I choose it to mean - neither more nor less." --- "The question is," said Alice, "whether you can make words mean so many different things." --- "The question is," said Humpty Dumpty, "which is to be master - that's all." --- "The question is," said Alice, "whether you can make words mean so many different things." --- "The question is," said Humpty Dumpty, "which is to be master - that's all." --- "The question is," said Humpty Dumpty, "which is to be master - that's all." Lewis Carroll, Through the Looking-Glass To come back to our initial question what is used in Python: The authors who call the mechanism call-by-value and those who call it call-by-reference are stretching the definitions until they fit. Correctly speaking, Python uses a mechanism, which is known as "Call-by-Object", sometimes also called "Call by Object Reference" or "Call by Sharing". To come back to our initial question what is used in Python: The authors who call the mechanism call-by-value and those who call it call-by-reference are stretching the definitions until they fit. Correctly speaking, Python uses a mechanism, which is known as "Call-by-Object", sometimes also called "Call by Object Reference" or "Call by Sharing". To come back to our initial question what is used in Python: The authors who call the mechanism call-by-value and those who call it call-by-reference are stretching the definitions until they fit. Correctly speaking, Python uses a mechanism, which is known as "Call-by-Object", sometimes also called "Call by Object Reference" or "Call by Sharing". Correctly speaking, Python uses a mechanism, which is known as "Call-by-Object", sometimes also called "Call by Object Reference" or "Call by Sharing". Paramterübergabe

If you pass immutable arguments like integers, strings or tuples to a function, the passing acts like call-by-value. The object reference is passed to the function parameters. They can't be changed within the function, because they can't be changed at all, i.e. they are immutable. It's different, if we pass mutable arguments. They are also passed by object reference, but they can be changed in place in the function. If we pass a list to a function, we have to consider two cases: Elements of a list can be changed in place, i.e. the list will be changed even in the caller's scope. If a new list is assigned to the name, the old list will not be affected, i.e. the list in the caller's scope will remain untouched. First, let's have a look at the integer variables. The parameter inside of the function remains a reference to the arguments variable, as long as the parameter is not changed. As soon as a new value will be assigned to it, Python creates a separate local variable. The caller's variable will not be changed this way: First, let's have a look at the integer variables. The parameter inside of the function remains a reference to the arguments variable, as long as the parameter is not changed. As soon as a new value will be assigned to it, Python creates a separate local variable. The caller's variable will not be changed this way: First, let's have a look at the integer variables. The parameter inside of the function remains a reference to the arguments variable, as long as the parameter is not changed. As soon as a new value will be assigned to it, Python creates a separate local variable. The caller's variable will not be changed this way:

def ref_demo(x):
    print "x=",x," id=",id(x)
    x=42
    print "x=",x," id=",id(x)
Paramterübergabe In the example above, we used the id() function, which takes an object as a parameter. id(obj) returns the "identity" of the object "obj". This identity, the return value of the function, is an integer which is unique and constant for this object during its lifetime. Two different objects with non-overlapping lifetimes may have the same id() value. If you call the function ref_demo() - like we do in the green block further down - we can check with the id() function what happens to x. We can see that in the main scope, x has the identity 41902552. In the first print statement of the ref_demo() function, the x from the main scope is used, because we can see that we get the same identity. After we have assigned the value 42 to x, x gets a new identity 41903752, i.e. a separate memory location from the global x. So, when we are back in the main scope x has still the original value 9. This means that Python initially behaves like call-by-reference, but as soon as we are changing the value of such a variable, Python "switches" to call-by-value. If you call the function ref_demo() - like we do in the green block further down - we can check with the id() function what happens to x. We can see that in the main scope, x has the identity 41902552. In the first print statement of the ref_demo() function, the x from the main scope is used, because we can see that we get the same identity. After we have assigned the value 42 to x, x gets a new identity 41903752, i.e. a separate memory location from the global x. So, when we are back in the main scope x has still the original value 9.

This means that Python initially behaves like call-by-reference, but as soon as we are changing the value of such a variable, Python "switches" to call-by-value. If you call the function ref_demo() - like we do in the green block further down - we can check with the id() function what happens to x. We can see that in the main scope, x has the identity 41902552.

In the first print statement of the ref_demo() function, the x from the main scope is used, because we can see that we get the same identity. After we have assigned the value 42 to x, x gets a new identity 41903752, i.e. a separate memory location from the global x. So, when we are back in the main scope x has still the original value 9.

This means that Python initially behaves like call-by-reference, but as soon as we are changing the value of such a variable, Python "switches" to call-by-value.

>>> x = 9
>>> id(x)
41902552
>>> ref_demo(x)
x= 9  id= 41902552
x= 42  id= 41903752
>>> id(x)
41902552
>>>
Side effects A function is said to have a side effect if, in addition to producing a value, it modifies the caller's environment in other ways. For example, a function might modify a global or static variable, modify one of its arguments, raise an exception, write data to a display or file and so on. In many cases these side effects are wanted, i.e. they are part of the functions specification.

But in other cases, they are not wanted , they are hidden side effects. In this chapter we are only interested in the side effects, which change global variables, which have been passed as arguments to a function. Let's assume, we are passing a list to a function. We expect that the function is not changing this list. First let's have a look at a function which has no side effects.

As a new list is assigned to the parameter list in func1(), a new memory location is created for list and list becomes a local variable. In many cases these side effects are wanted, i.e. they are part of the functions specification. But in other cases, they are not wanted , they are hidden side effects. In this chapter we are only interested in the side effects, which change global variables, which have been passed as arguments to a function. Let's assume, we are passing a list to a function. We expect that the function is not changing this list. First let's have a look at a function which has no side effects. As a new list is assigned to the parameter list in func1(), a new memory location is created for list and list becomes a local variable. In many cases these side effects are wanted, i.e. they are part of the functions specification. But in other cases, they are not wanted , they are hidden side effects. In this chapter we are only interested in the side effects, which change global variables, which have been passed as arguments to a function. Let's assume, we are passing a list to a function. We expect that the function is not changing this list. First let's have a look at a function which has no side effects. As a new list is assigned to the parameter list in func1(), a new memory location is created for list and list becomes a local variable. Let's assume, we are passing a list to a function. We expect that the function is not changing this list. First let's have a look at a function which has no side effects. As a new list is assigned to the parameter list in func1(), a new memory location is created for list and list becomes a local variable.

>>> def func1(list):
...     print list
...     list = [47,11]
...     print list
... 
>>> fib = [0,1,1,2,3,5,8]
>>> func1(fib)
[0, 1, 1, 2, 3, 5, 8]
[47, 11]
>>> print fib
[0, 1, 1, 2, 3, 5, 8]
>>>
This changes drastically, if we include something in the list by using +=. To show this, we have a different function func2() in the following example:
>>> def func2(list):
...     print list
...     list += [47,11]
...     print list
... 
>>> fib = [0,1,1,2,3,5,8]
>>> func2(fib)
[0, 1, 1, 2, 3, 5, 8]
[0, 1, 1, 2, 3, 5, 8, 47, 11]
>>> print fib
[0, 1, 1, 2, 3, 5, 8, 47, 11]
>>>
The user of the function can prevent this by passing a copy to the function. In this case a shallow copy is sufficient:
>>> def func2(list):
...     print list
...     list += [47,11]
...     print list
... 
>>> fib = [0,1,1,2,3,5,8]
>>> func2(fib[:])
[0, 1, 1, 2, 3, 5, 8]
[0, 1, 1, 2, 3, 5, 8, 47, 11]
>>> print fib
[0, 1, 1, 2, 3, 5, 8]
>>>
Command Line Arguments It's possible to write Python scripts using command line arguments. If you call a Python script from a shell, the arguments are placed after the script name. The arguments are separated by spaces. Inside of the script these arguments are accessible through the list variable sys.argv. The name of the script is included in this list sys.argv[0]. sys.argv[1] contains the first parameter, sys.argv[2] the second and so on. The following script (arguments.py) prints all arguments: The following script (arguments.py) prints all arguments:
 # Module sys has to be imported:
import sys                

# Iteration over all arguments:
for eachArg in sys.argv:   
        print eachArg
Example call to this script:
python argumente.py python course for beginners
This call creates the following output:
argumente.py
python
course
for
beginners
Variable Length of Parameters We will introduce now functions, which can take an arbitrary number of arguments. Those who have some programming background in C or C++ know this from the varargs feature of these languages. The asterisk "*" is used in Python to define a variable number of arguments. The asterisk character has to precede a variable identifier in the parameter list.
>>> def varpafu(*x): print(x)
... 
>>> varpafu()
()
>>> varpafu(34,"Do you like Python?", "Of course")
(34, 'Do you like Python?', 'Of course')
>>>
We learn from the previous example that the arguments passed to the function call of varpafu() are collected in a tuple, which can be accessed as a "normal" variable x within the body of the function. If the function is called without any arguments, the value of x is an empty tuple. Sometimes, it's necessary to use positional parameters followed by an arbitrary number of parameters in a function definition. This is possible, but the positional parameters always have to precede the arbitrary parameters. In the following example, we have a positional parameter "city", - the main location, - which always have to be given, followed by an arbitrary number of other locations: Sometimes, it's necessary to use positional parameters followed by an arbitrary number of parameters in a function definition. This is possible, but the positional parameters always have to precede the arbitrary parameters. In the following example, we have a positional parameter "city", - the main location, - which always have to be given, followed by an arbitrary number of other locations: Sometimes, it's necessary to use positional parameters followed by an arbitrary number of parameters in a function definition. This is possible, but the positional parameters always have to precede the arbitrary parameters. In the following example, we have a positional parameter "city", - the main location, - which always have to be given, followed by an arbitrary number of other locations:
>>> def locations(city, *other_cities): print(city, other_cities)
... 
>>> locations("Paris")
('Paris', ())
>>> locations("Paris", "Strasbourg", "Lyon", "Dijon", "Bordeaux", "Marseille")
('Paris', ('Strasbourg', 'Lyon', 'Dijon', 'Bordeaux', 'Marseille'))
>>>
Exercise Write a function which calculates the arithmetic mean of a variable number of values.
Solution
Nov 23, 2019 | www.python-course.eu
def arithmetic_mean(x, *l):
    """ The function calculates the arithmetic mean of a non-empty
        arbitrary number of numbers """
    sum = x
    for i in l:
        sum += i

    return sum / (1.0 + len(l))
You might ask yourself, why we used both a positional parameter "x" and the variable parameter "*l" in our function definition. We could have only used *l to contain all our numbers. The idea is that we wanted to enforce that we always have a non-empty list of numbers. This is necessary to prevent a division by zero error, because the average of a an empty list of numbers is not defined.

In the following interactive Python session, we can learn how to use this function. We assume that the function arithmetic_mean is saved in a file called statistics.py.

>>> from statistics import arithmetic_mean
>>> arithmetic_mean(4,7,9)
6.666666666666667
>>> arithmetic_mean(4,7,9,45,-3.7,99)
26.71666666666667
This works fine, but there is a catch. What if somebody wants to call the function with a list, instead of a variable number of numbers, as we have shown above? We can see in the following that we raise an error, as most hopefully, you might expect:
>>> l = [4,7,9,45,-3.7,99]
>>> arithmetic_mean(l)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "statistics.py", line 8, in arithmetic_mean
    return sum / (1.0 + len(l))
TypeError: unsupported operand type(s) for /: 'list' and 'float'
The rescue is using another asterisk:
>>> arithmetic_mean(*l)
26.71666666666667
>>>

* in Function Calls A * can appear in function calls as well, as we have just seen in the previous exercise: The semantics is in this case "inverse" to a star in a function definition. An argument will be unpacked and not packed. In other words, the elements of the list or tuple are singularized:

>>> def f(x,y,z):
...     print(x,y,z)
... 
>>> p = (47,11,12)
>>> f(*p)
(47, 11, 12)
There is hardly any need to mention that this way of calling our function is more comfortable the following one:
>>> f(p[0],p[1],p[2])
(47, 11, 12)
>>>
Additionally to being less comfortable, the previous call (f(p[0],p[1],p[2])) doesn't work in the general case, i.e. lists of unknown lengths. "Unknown" mean, that the length is only known at runtime and not when we are writing the script. Arbitrary Keyword Parameters There is also a mechanism for an arbitrary number of keyword parameters. To do this, we use the double asterisk "**" notation:
>>> def f(**args):
...     print(args)
... 
>>> f()
{}
>>> f(de="German",en="English",fr="French")
{'fr': 'French', 'de': 'German', 'en': 'English'}
>>>
Double Asterisk in Function Calls The following example demonstrates the usage of ** in a function call:
>>> def f(a,b,x,y):
...     print(a,b,x,y)
...
>>> d = {'a':'append', 'b':'block','x':'extract','y':'yes'}
>>> f(**d)
('append', 'block', 'extract', 'yes')
and now in combination with *:
>>> t = (47,11)
>>> d = {'x':'extract','y':'yes'}
>>> f(*t, **d)
(47, 11, 'extract', 'yes')
>>>

[Aug 09, 2020] What is the Python equivalent of Perl's 'if exists' for hashes

Aug 09, 2020 | stackoverflow.com

flybonzai ,

I'm writing a script for work, and need to be able to create a hash of arrays that will check to see if a key exists in the hash (or dictionary), and if it does I will roll up some values from the new line into the existing hash values. Here is my code in Perl, what would be the translation in Python?

if (exists($rollUpHash{$hashKey}))
        {
          say("Same key found, summing up!")
          $rollUpHash{$hashKey}[14] += $lineFields[14];
          $rollUpHash{$hashKey}[15] += $lineFields[15];
          $rollUpHash{$hashKey}[16] += $lineFields[16];
          $rollUpHash{$hashKey}[17] += $lineFields[17];
          $rollUpHash{$hashKey}[24] += $lineFields[24];
          push @{$rollUpHash{$hashKey}}, $sumDeduct_NonDeduct_ytd;
          # print %rollUpHash;
        }
      else
        {
          $rollUpHash{$hashKey} = \@lineFields;
        }

ikegami ,

You might also want to look at a collections.defaultdict docs.python.org/2/library/Padraic Cunningham Jul 22 '15 at 20:35

> ,

If you're just checking if the key exists, you can do if "key" in your_dictionary

Edit:

To handle the unintended second part of your question, about adding the new value to the array, you can do something like this

# -1 will give you the last item in the list every time
for key, value in nums.iteritems():
    nums[key].append(value[-1]+value[-1])

[Jul 29, 2020] statistics -- Mathematical statistics functions -- Python 3.8.5 documentation

Jul 29, 2020 | docs.python.org

statistics -- Mathematical statistics functions

New in version 3.4.

Source code: Lib/statistics.py


This module provides functions for calculating mathematical statistics of numeric ( Real -valued) data.

The module is not intended to be a competitor to third-party libraries such as NumPy , SciPy , or proprietary full-featured statistics packages aimed at professional statisticians such as Minitab, SAS and Matlab. It is aimed at the level of graphing and scientific calculators.

Unless explicitly noted, these functions support int , float , Decimal and Fraction . Behaviour with other types (whether in the numeric tower or not) is currently unsupported. Collections with a mix of types are also undefined and implementation-dependent. If your input data consists of mixed types, you may be able to use map() to ensure a consistent result, for example: map(float, input_data) .

Averages and measures of central location

These functions calculate an average or typical value from a population or sample.

mean()

Arithmetic mean ("average") of data.

fmean()

Fast, floating point arithmetic mean.

geometric_mean()

Geometric mean of data.

harmonic_mean()

Harmonic mean of data.

median()

Median (middle value) of data.

median_low()

Low median of data.

median_high()

High median of data.

median_grouped()

Median, or 50th percentile, of grouped data.

mode()

Single mode (most common value) of discrete or nominal data.

multimode()

List of modes (most common values) of discrete or nomimal data.

quantiles()

Divide data into intervals with equal probability.

Measures of spread

These functions calculate a measure of how much the population or sample tends to deviate from the typical or average values.

pstdev()

Population standard deviation of data.

pvariance()

Population variance of data.

stdev()

Sample standard deviation of data.

variance()

Sample variance of data.

Function details

Note: The functions do not require the data given to them to be sorted. However, for reading convenience, most of the examples show sorted sequences.

statistics. mean ( data )

Return the sample arithmetic mean of data which can be a sequence or iterable.

The arithmetic mean is the sum of the data divided by the number of data points. It is commonly called "the average", although it is only one of many different mathematical averages. It is a measure of the central location of the data.

If data is empty, StatisticsError will be raised.

Some examples of use:

>>> mean([1, 2, 3, 4, 4])
2.8
>>> mean([-1.0, 2.5, 3.25, 5.75])
2.625

>>> from fractions import Fraction as F
>>> mean([F(3, 7), F(1, 21), F(5, 3), F(1, 3)])
Fraction(13, 21)

>>> from decimal import Decimal as D
>>> mean([D("0.5"), D("0.75"), D("0.625"), D("0.375")])
Decimal('0.5625')

Note

The mean is strongly affected by outliers and is not a robust estimator for central location: the mean is not necessarily a typical example of the data points. For more robust measures of central location, see median() and mode() .

The sample mean gives an unbiased estimate of the true population mean, so that when taken on average over all the possible samples, mean(sample) converges on the true mean of the entire population. If data represents the entire population rather than a sample, then mean(data) is equivalent to calculating the true population mean μ.

statistics. fmean ( data )

Convert data to floats and compute the arithmetic mean.

This runs faster than the mean() function and it always returns a float . The data may be a sequence or iterable. If the input dataset is empty, raises a StatisticsError .

>>> fmean([3.5, 4.0, 5.25])
4.25

New in version 3.8.

statistics. geometric_mean ( data )

Convert data to floats and compute the geometric mean.

The geometric mean indicates the central tendency or typical value of the data using the product of the values (as opposed to the arithmetic mean which uses their sum).

Raises a StatisticsError if the input dataset is empty, if it contains a zero, or if it contains a negative value. The data may be a sequence or iterable.

No special efforts are made to achieve exact results. (However, this may change in the future.)

>>> round(geometric_mean([54, 24, 36]), 1)
36.0

New in version 3.8.

statistics. harmonic_mean ( data )

Return the harmonic mean of data , a sequence or iterable of real-valued numbers.

The harmonic mean, sometimes called the subcontrary mean, is the reciprocal of the arithmetic mean() of the reciprocals of the data. For example, the harmonic mean of three values a , b and c will be equivalent to 3/(1/a + 1/b + 1/c) . If one of the values is zero, the result will be zero.

The harmonic mean is a type of average, a measure of the central location of the data. It is often appropriate when averaging rates or ratios, for example speeds.

Suppose a car travels 10 km at 40 km/hr, then another 10 km at 60 km/hr. What is the average speed?

>>> harmonic_mean([40, 60])
48.0

Suppose an investor purchases an equal value of shares in each of three companies, with P/E (price/earning) ratios of 2.5, 3 and 10. What is the average P/E ratio for the investor's portfolio?

>>> harmonic_mean([2.5, 3, 10])  # For an equal investment portfolio.
3.6

StatisticsError is raised if data is empty, or any element is less than zero.

The current algorithm has an early-out when it encounters a zero in the input. This means that the subsequent inputs are not tested for validity. (This behavior may change in the future.)

New in version 3.6.

statistics. median ( data )

Return the median (middle value) of numeric data, using the common "mean of middle two" method. If data is empty, StatisticsError is raised. data can be a sequence or iterable.

The median is a robust measure of central location and is less affected by the presence of outliers. When the number of data points is odd, the middle data point is returned:

>>> median([1, 3, 5])
3

When the number of data points is even, the median is interpolated by taking the average of the two middle values:

>>> median([1, 3, 5, 7])
4.0

This is suited for when your data is discrete, and you don't mind that the median may not be an actual data point.

If the data is ordinal (supports order operations) but not numeric (doesn't support addition), consider using median_low() or median_high() instead.

statistics. median_low ( data )

Return the low median of numeric data. If data is empty, StatisticsError is raised. data can be a sequence or iterable.

The low median is always a member of the data set. When the number of data points is odd, the middle value is returned. When it is even, the smaller of the two middle values is returned.

>>> median_low([1, 3, 5])
3
>>> median_low([1, 3, 5, 7])
3

Use the low median when your data are discrete and you prefer the median to be an actual data point rather than interpolated.

statistics. median_high ( data )

Return the high median of data. If data is empty, StatisticsError is raised. data can be a sequence or iterable.

The high median is always a member of the data set. When the number of data points is odd, the middle value is returned. When it is even, the larger of the two middle values is returned.

>>> median_high([1, 3, 5])
3
>>> median_high([1, 3, 5, 7])
5

Use the high median when your data are discrete and you prefer the median to be an actual data point rather than interpolated.

statistics. median_grouped ( data , interval=1 )

Return the median of grouped continuous data, calculated as the 50th percentile, using interpolation. If data is empty, StatisticsError is raised. data can be a sequence or iterable.

>>> median_grouped([52, 52, 53, 54])
52.5

In the following example, the data are rounded, so that each value represents the midpoint of data classes, e.g. 1 is the midpoint of the class 0.5–1.5, 2 is the midpoint of 1.5–2.5, 3 is the midpoint of 2.5–3.5, etc. With the data given, the middle value falls somewhere in the class 3.5–4.5, and interpolation is used to estimate it:

>>> median_grouped([1, 2, 2, 3, 4, 4, 4, 4, 4, 5])
3.7

Optional argument interval represents the class interval, and defaults to 1. Changing the class interval naturally will change the interpolation:

>>> median_grouped([1, 3, 3, 5, 7], interval=1)
3.25
>>> median_grouped([1, 3, 3, 5, 7], interval=2)
3.5

This function does not check whether the data points are at least interval apart.

CPython implementation detail: Under some circumstances, median_grouped() may coerce data points to floats. This behaviour is likely to change in the future.

See also

  • "Statistics for the Behavioral Sciences", Frederick J Gravetter and Larry B Wallnau (8th Edition).

  • The SSMEDIAN function in the Gnome Gnumeric spreadsheet, including this discussion .

statistics. mode ( data )

Return the single most common data point from discrete or nominal data . The mode (when it exists) is the most typical value and serves as a measure of central location.

If there are multiple modes with the same frequency, returns the first one encountered in the data . If the smallest or largest of those is desired instead, use min(multimode(data)) or max(multimode(data)) . If the input data is empty, StatisticsError is raised.

mode assumes discrete data and returns a single value. This is the standard treatment of the mode as commonly taught in schools:

>>> mode([1, 1, 2, 3, 3, 3, 3, 4])
3

The mode is unique in that it is the only statistic in this package that also applies to nominal (non-numeric) data:

>>> mode(["red", "blue", "blue", "red", "green", "red", "red"])
'red'

Changed in version 3.8: Now handles multimodal datasets by returning the first mode encountered. Formerly, it raised StatisticsError when more than one mode was found.

statistics. multimode ( data )

Return a list of the most frequently occurring values in the order they were first encountered in the data . Will return more than one result if there are multiple modes or an empty list if the data is empty:

>>> multimode('aabbbbccddddeeffffgg')
['b', 'd', 'f']
>>> multimode('')
[]

New in version 3.8.

statistics. pstdev ( data , mu=None )

Return the population standard deviation (the square root of the population variance). See pvariance() for arguments and other details.

>>> pstdev([1.5, 2.5, 2.5, 2.75, 3.25, 4.75])
0.986893273527251
statistics. pvariance ( data , mu=None )

Return the population variance of data , a non-empty sequence or iterable of real-valued numbers. Variance, or second moment about the mean, is a measure of the variability (spread or dispersion) of data. A large variance indicates that the data is spread out; a small variance indicates it is clustered closely around the mean.

If the optional second argument mu is given, it is typically the mean of the data . It can also be used to compute the second moment around a point that is not the mean. If it is missing or None (the default), the arithmetic mean is automatically calculated.

Use this function to calculate the variance from the entire population. To estimate the variance from a sample, the variance() function is usually a better choice.

Raises StatisticsError if data is empty.

Examples:

>>> data = [0.0, 0.25, 0.25, 1.25, 1.5, 1.75, 2.75, 3.25]
>>> pvariance(data)
1.25

If you have already calculated the mean of your data, you can pass it as the optional second argument mu to avoid recalculation:

>>> mu = mean(data)
>>> pvariance(data, mu)
1.25

Decimals and Fractions are supported:

>>> from decimal import Decimal as D
>>> pvariance([D("27.5"), D("30.25"), D("30.25"), D("34.5"), D("41.75")])
Decimal('24.815')

>>> from fractions import Fraction as F
>>> pvariance([F(1, 4), F(5, 4), F(1, 2)])
Fraction(13, 72)

Note

When called with the entire population, this gives the population variance σ². When called on a sample instead, this is the biased sample variance s², also known as variance with N degrees of freedom.

If you somehow know the true population mean μ, you may use this function to calculate the variance of a sample, giving the known population mean as the second argument. Provided the data points are a random sample of the population, the result will be an unbiased estimate of the population variance.

statistics. stdev ( data , xbar=None )

Return the sample standard deviation (the square root of the sample variance). See variance() for arguments and other details.

>>> stdev([1.5, 2.5, 2.5, 2.75, 3.25, 4.75])
1.0810874155219827
statistics. variance ( data , xbar=None )

Return the sample variance of data , an iterable of at least two real-valued numbers. Variance, or second moment about the mean, is a measure of the variability (spread or dispersion) of data. A large variance indicates that the data is spread out; a small variance indicates it is clustered closely around the mean.

If the optional second argument xbar is given, it should be the mean of data . If it is missing or None (the default), the mean is automatically calculated.

Use this function when your data is a sample from a population. To calculate the variance from the entire population, see pvariance() .

Raises StatisticsError if data has fewer than two values.

Examples:

>>> data = [2.75, 1.75, 1.25, 0.25, 0.5, 1.25, 3.5]
>>> variance(data)
1.3720238095238095

If you have already calculated the mean of your data, you can pass it as the optional second argument xbar to avoid recalculation:

>>> m = mean(data)
>>> variance(data, m)
1.3720238095238095

This function does not attempt to verify that you have passed the actual mean as xbar . Using arbitrary values for xbar can lead to invalid or impossible results.

Decimal and Fraction values are supported:

>>> from decimal import Decimal as D
>>> variance([D("27.5"), D("30.25"), D("30.25"), D("34.5"), D("41.75")])
Decimal('31.01875')

>>> from fractions import Fraction as F
>>> variance([F(1, 6), F(1, 2), F(5, 3)])
Fraction(67, 108)

Note

This is the sample variance s² with Bessel's correction, also known as variance with N-1 degrees of freedom. Provided that the data points are representative (e.g. independent and identically distributed), the result should be an unbiased estimate of the true population variance.

If you somehow know the actual population mean μ you should pass it to the pvariance() function as the mu parameter to get the variance of a sample.

statistics. quantiles ( data , * , n=4 , method='exclusive' )

Divide data into n continuous intervals with equal probability. Returns a list of n - 1 cut points separating the intervals.

Set n to 4 for quartiles (the default). Set n to 10 for deciles. Set n to 100 for percentiles which gives the 99 cuts points that separate data into 100 equal sized groups. Raises StatisticsError if n is not least 1.

The data can be any iterable containing sample data. For meaningful results, the number of data points in data should be larger than n . Raises StatisticsError if there are not at least two data points.

The cut points are linearly interpolated from the two nearest data points. For example, if a cut point falls one-third of the distance between two sample values, 100 and 112 , the cut-point will evaluate to 104 .

The method for computing quantiles can be varied depending on whether the data includes or excludes the lowest and highest possible values from the population.

The default method is "exclusive" and is used for data sampled from a population that can have more extreme values than found in the samples. The portion of the population falling below the i-th of m sorted data points is computed as i / (m + 1) . Given nine sample values, the method sorts them and assigns the following percentiles: 10%, 20%, 30%, 40%, 50%, 60%, 70%, 80%, 90%.

Setting the method to "inclusive" is used for describing population data or for samples that are known to include the most extreme values from the population. The minimum value in data is treated as the 0th percentile and the maximum value is treated as the 100th percentile. The portion of the population falling below the i-th of m sorted data points is computed as (i - 1) / (m - 1) . Given 11 sample values, the method sorts them and assigns the following percentiles: 0%, 10%, 20%, 30%, 40%, 50%, 60%, 70%, 80%, 90%, 100%.

# Decile cut points for empirically sampled data
>>> data = [105, 129, 87, 86, 111, 111, 89, 81, 108, 92, 110,
...         100, 75, 105, 103, 109, 76, 119, 99, 91, 103, 129,
...         106, 101, 84, 111, 74, 87, 86, 103, 103, 106, 86,
...         111, 75, 87, 102, 121, 111, 88, 89, 101, 106, 95,
...         103, 107, 101, 81, 109, 104]
>>> [round(q, 1) for q in quantiles(data, n=10)]
[81.0, 86.2, 89.0, 99.4, 102.5, 103.6, 106.0, 109.8, 111.0]

New in version 3.8.

Exceptions

A single exception is defined:

exception statistics. StatisticsError

Subclass of ValueError for statistics-related exceptions.

NormalDist objects

NormalDist is a tool for creating and manipulating normal distributions of a random variable . It is a class that treats the mean and standard deviation of data measurements as a single entity.

Normal distributions arise from the Central Limit Theorem and have a wide range of applications in statistics.

class statistics. NormalDist ( mu=0.0 , sigma=1.0 )

Returns a new NormalDist object where mu represents the arithmetic mean and sigma represents the standard deviation .

If sigma is negative, raises StatisticsError .

mean

A read-only property for the arithmetic mean of a normal distribution.

median

A read-only property for the median of a normal distribution.

mode

A read-only property for the mode of a normal distribution.

stdev

A read-only property for the standard deviation of a normal distribution.

variance

A read-only property for the variance of a normal distribution. Equal to the square of the standard deviation.

classmethod from_samples ( data )

Makes a normal distribution instance with mu and sigma parameters estimated from the data using fmean() and stdev() .

The data can be any iterable and should consist of values that can be converted to type float . If data does not contain at least two elements, raises StatisticsError because it takes at least one point to estimate a central value and at least two points to estimate dispersion.

samples ( n , * , seed=None )

Generates n random samples for a given mean and standard deviation. Returns a list of float values.

If seed is given, creates a new instance of the underlying random number generator. This is useful for creating reproducible results, even in a multi-threading context.

pdf ( x )

Using a probability density function (pdf) , compute the relative likelihood that a random variable X will be near the given value x . Mathematically, it is the limit of the ratio P(x <= X < x+dx) / dx as dx approaches zero.

The relative likelihood is computed as the probability of a sample occurring in a narrow range divided by the width of the range (hence the word "density"). Since the likelihood is relative to other points, its value can be greater than 1.0 .

cdf ( x )

Using a cumulative distribution function (cdf) , compute the probability that a random variable X will be less than or equal to x . Mathematically, it is written P(X <= x) .

inv_cdf ( p )

Compute the inverse cumulative distribution function, also known as the quantile function or the percent-point function. Mathematically, it is written x : P(X <= x) = p .

Finds the value x of the random variable X such that the probability of the variable being less than or equal to that value equals the given probability p .

overlap ( other )

Measures the agreement between two normal probability distributions. Returns a value between 0.0 and 1.0 giving the overlapping area for the two probability density functions .

quantiles ( n=4 )

Divide the normal distribution into n continuous intervals with equal probability. Returns a list of (n - 1) cut points separating the intervals.

Set n to 4 for quartiles (the default). Set n to 10 for deciles. Set n to 100 for percentiles which gives the 99 cuts points that separate the normal distribution into 100 equal sized groups.

Instances of NormalDist support addition, subtraction, multiplication and division by a constant. These operations are used for translation and scaling. For example:

>>> temperature_february = NormalDist(5, 2.5)             # Celsius
>>> temperature_february * (9/5) + 32                     # Fahrenheit
NormalDist(mu=41.0, sigma=4.5)

Dividing a constant by an instance of NormalDist is not supported because the result wouldn't be normally distributed.

Since normal distributions arise from additive effects of independent variables, it is possible to add and subtract two independent normally distributed random variables represented as instances of NormalDist . For example:

>>> birth_weights = NormalDist.from_samples([2.5, 3.1, 2.1, 2.4, 2.7, 3.5])
>>> drug_effects = NormalDist(0.4, 0.15)
>>> combined = birth_weights + drug_effects
>>> round(combined.mean, 1)
3.1
>>> round(combined.stdev, 1)
0.5

New in version 3.8.

NormalDist Examples and Recipes

NormalDist readily solves classic probability problems.

For example, given historical data for SAT exams showing that scores are normally distributed with a mean of 1060 and a standard deviation of 195, determine the percentage of students with test scores between 1100 and 1200, after rounding to the nearest whole number:

>>> sat = NormalDist(1060, 195)
>>> fraction = sat.cdf(1200 + 0.5) - sat.cdf(1100 - 0.5)
>>> round(fraction * 100.0, 1)
18.4

Find the quartiles and deciles for the SAT scores:

>>> list(map(round, sat.quantiles()))
[928, 1060, 1192]
>>> list(map(round, sat.quantiles(n=10)))
[810, 896, 958, 1011, 1060, 1109, 1162, 1224, 1310]

To estimate the distribution for a model than isn't easy to solve analytically, NormalDist can generate input samples for a Monte Carlo simulation :

>>> def model(x, y, z):
...     return (3*x + 7*x*y - 5*y) / (11 * z)
...
>>> n = 100_000
>>> X = NormalDist(10, 2.5).samples(n, seed=3652260728)
>>> Y = NormalDist(15, 1.75).samples(n, seed=4582495471)
>>> Z = NormalDist(50, 1.25).samples(n, seed=6582483453)
>>> quantiles(map(model, X, Y, Z))       
[1.4591308524824727, 1.8035946855390597, 2.175091447274739]

Normal distributions can be used to approximate Binomial distributions when the sample size is large and when the probability of a successful trial is near 50%.

For example, an open source conference has 750 attendees and two rooms with a 500 person capacity. There is a talk about Python and another about Ruby. In previous conferences, 65% of the attendees preferred to listen to Python talks. Assuming the population preferences haven't changed, what is the probability that the Python room will stay within its capacity limits?

>>> n = 750             # Sample size
>>> p = 0.65            # Preference for Python
>>> q = 1.0 - p         # Preference for Ruby
>>> k = 500             # Room capacity

>>> # Approximation using the cumulative normal distribution
>>> from math import sqrt
>>> round(NormalDist(mu=n*p, sigma=sqrt(n*p*q)).cdf(k + 0.5), 4)
0.8402

>>> # Solution using the cumulative binomial distribution
>>> from math import comb, fsum
>>> round(fsum(comb(n, r) * p**r * q**(n-r) for r in range(k+1)), 4)
0.8402

>>> # Approximation using a simulation
>>> from random import seed, choices
>>> seed(8675309)
>>> def trial():
...     return choices(('Python', 'Ruby'), (p, q), k=n).count('Python')
>>> mean(trial() <= k for i in range(10_000))
0.8398

Normal distributions commonly arise in machine learning problems.

Wikipedia has a nice example of a Naive Bayesian Classifier . The challenge is to predict a person's gender from measurements of normally distributed features including height, weight, and foot size.

We're given a training dataset with measurements for eight people. The measurements are assumed to be normally distributed, so we summarize the data with NormalDist :

>>> height_male = NormalDist.from_samples([6, 5.92, 5.58, 5.92])
>>> height_female = NormalDist.from_samples([5, 5.5, 5.42, 5.75])
>>> weight_male = NormalDist.from_samples([180, 190, 170, 165])
>>> weight_female = NormalDist.from_samples([100, 150, 130, 150])
>>> foot_size_male = NormalDist.from_samples([12, 11, 12, 10])
>>> foot_size_female = NormalDist.from_samples([6, 8, 7, 9])

Next, we encounter a new person whose feature measurements are known but whose gender is unknown:

>>> ht = 6.0        # height
>>> wt = 130        # weight
>>> fs = 8          # foot size

Starting with a 50% prior probability of being male or female, we compute the posterior as the prior times the product of likelihoods for the feature measurements given the gender:

>>> prior_male = 0.5
>>> prior_female = 0.5
>>> posterior_male = (prior_male * height_male.pdf(ht) *
...                   weight_male.pdf(wt) * foot_size_male.pdf(fs))

>>> posterior_female = (prior_female * height_female.pdf(ht) *
...                     weight_female.pdf(wt) * foot_size_female.pdf(fs))

The final prediction goes to the largest posterior. This is known as the maximum a posteriori or MAP:

>>> 'male' if posterior_male > posterior_female else 'female'
'f

[Jul 28, 2020] Intro into Python functions

Jul 28, 2020 | my.safaribooksonline.com

FUNCTIONS

You're already familiar with the print() , input() , and len() functions from the previous chapters. Python provides several built-in functions like these, but you can also write your own functions. A function is like a miniprogram within a program.

To better understand how functions work, let's create one. Enter this program into the file editor and save it as helloFunc.py :

➊ def hello():
➋ print('Howdy!')
print('Howdy!!!')
print('Hello there.')

➌ hello()
hello()
hello()

You can view the execution of this program at https://autbor.com/hellofunc/ . The first line is a def statement ➊ , which defines a function named hello() . The code in the block that follows the def statement ➋ is the body of the function. This code is executed when the function is called, not when the function is first defined.

The hello() lines after the function ➌ are function calls. In code, a function call is just the function's name followed by parentheses, possibly with some number of arguments in between the parentheses. When the program execution reaches these calls, it will jump to the top line in the function and begin executing the code there. When it reaches the end of the function, the execution returns to the line that called the function and continues moving through the code as before.

Since this program calls hello() three times, the code in the hello() function is executed three times. When you run this program, the output looks like this:

Howdy!
Howdy!!!
Hello there.
Howdy!
Howdy!!!
Hello there.
Howdy!
Howdy!!!
Hello there.

A major purpose of functions is to group code that gets executed multiple times. Without a function defined, you would have to copy and paste this code each time, and the program would look like this:

print('Howdy!')
print('Howdy!!!')
print('Hello there.')
print('Howdy!')
print('Howdy!!!')
print('Hello there.')
print('Howdy!')
print('Howdy!!!')
print('Hello there.')

In general, you always want to avoid duplicating code because if you ever decide to update the code -- if, for example, you find a bug you need to fix -- you'll have to remember to change the code everywhere you copied it.

As you get more programming experience, you'll often find yourself deduplicating code, which means getting rid of duplicated or copy-and-pasted code. Deduplication makes your programs shorter, easier to read, and easier to update.

def Statements with Parameters

When you call the print() or len() function, you pass them values, called arguments , by typing them between the parentheses. You can also define your own functions that accept arguments. Type this example into the file editor and save it as helloFunc2.py :


def hello(name):
print('Hello, ' + name)➋


hello('Alice')
hello('Bob')

When you run this program, the output looks like this:

Hello, Alice
Hello, Bob

You can view the execution of this program at https://autbor.com/hellofunc2/ . The definition of the hello() function in this program has a parameter called name ➊ . Parameters are variables that contain arguments. When a function is called with arguments, the arguments are stored in the parameters. The first time the hello() function is called, it is passed the argument 'Alice' ➌ . The program execution enters the function, and the parameter name is automatically set to 'Alice' , which is what gets printed by the print() statement ➋ .

One special thing to note about parameters is that the value stored in a parameter is forgotten when the function returns. For example, if you added print(name) after hello('Bob') in the previous program, the program would give you a NameError because there is no variable named name . This variable is destroyed after the function call hello('Bob') returns, so print(name) would refer to a name variable that does not exist.

This is similar to how a program's variables are forgotten when the program terminates. I'll talk more about why that happens later in the chapter, when I discuss what a function's local scope is.

Define, Call, Pass, Argument, Parameter

The terms define , call , pass , argument , and parameter can be confusing. Let's look at a code example to review these terms:


def sayHello(name):
print('Hello, ' + name)

sayHello('Al')

To define a function is to create it, just like an assignment statement like spam = 42 creates the spam variable. The def statement defines the sayHello() function ➊ . The sayHello('Al') line ➋ calls the now-created function, sending the execution to the top of the function's code. This function call is also known as passing the string value 'Al' to the function. A value being passed to a function in a function call is an argument . The argument 'Al' is assigned to a local variable named name . Variables that have arguments assigned to them are parameters .

It's easy to mix up these terms, but keeping them straight will ensure that you know precisely what the text in this chapter means.

Return Values and return Statements

When you call the len() function and pass it an argument such as 'Hello' , the function call evaluates to the integer value 5 , which is the length of the string you passed it. In general, the value that a function call evaluates to is called the return value of the function.

When creating a function using the def statement, you can specify what the return value should be with a return statement. A return statement consists of the following:

When an expression is used with a return statement, the return value is what this expression evaluates to. For example, the following program defines a function that returns a different string depending on what number it is passed as an argument. Enter this code into the file editor and save it as magic8Ball.py :

➊ import random

➋ def getAnswer(answerNumber):
➌ if answerNumber == 1:
return 'Gold will go up'
elif answerNumber == 2:
return 'Gol will go down'
elif answerNumber == 3:
return 'Silver will go up'
elif answerNumber == 4:
return 'Silver will go down'
elif answerNumber == 5:
return 'Platinum will go upr'
elif answerNumber == 6:
return 'Platinum will go down'
elif answerNumber == 7:
return 'Palladium will go up'
elif answerNumber == 8:
return 'Palladium will go down '
elif answerNumber == 9:
return 'All precious metals will go up'

➍ r = random.randint(1, 9)
➎ fortune = getAnswer(r)
➏ print(fortune)

You can view the execution of this program at https://autbor.com/magic8ball/ . When this program starts, Python first imports the random module ➊ . Then the getAnswer() function is defined ➋ . Because the function is being defined (and not called), the execution skips over the code in it. Next, the random.randint() function is called with two arguments: 1 and 9 ➍ . It evaluates to a random integer between 1 and 9 (including 1 and 9 themselves), and this value is stored in a variable named r .

The getAnswer() function is called with r as the argument ➎ . The program execution moves to the top of the getAnswer() function ➌ , and the value r is stored in a parameter named answerNumber . Then, depending on the value in answerNumber , the function returns one of many possible string values. The program execution returns to the line at the bottom of the program that originally called getAnswer() ➎ . The returned string is assigned to a variable named fortune , which then gets passed to a print() call ➏ and is printed to the screen.

Note that since you can pass return values as an argument to another function call, you could shorten these three lines:

r = random.randint(1, 9)
fortune = getAnswer(r)
print(fortune)

to this single equivalent line:

print(getAnswer(random.randint(1, 9)))

Remember, expressions are composed of values and operators. A function call can be used in an expression because the call evaluates to its return value.

The None Value

In Python, there is a value called None , which represents the absence of a value. The None value is the only value of the NoneType data type. (Other programming languages might call this value null , nil , or undefined .) Just like the Boolean True and False values, None must be typed with a capital N .

This value-without-a-value can be helpful when you need to store something that won't be confused for a real value in a variable. One place where None is used is as the return value of print() . The print() function displays text on the screen, but it doesn't need to return anything in the same way len() or input() does. But since all function calls need to evaluate to a return value, print() returns None . To see this in action, enter the following into the interactive shell:

>>> spam = print('Hello!')
Hello!
>>> None == spam
True

Behind the scenes, Python adds return None to the end of any function definition with no return statement. This is similar to how a while or for loop implicitly ends with a continue statement. Also, if you use a return statement without a value (that is, just the return keyword by itself), then None is returned.

Keyword Arguments and the print() Function

Most arguments are identified by their position in the function call. For example, random.randint(1, 10) is different from random.randint(10, 1) . The function call random.randint(1, 10) will return a random integer between 1 and 10 because the first argument is the low end of the range and the second argument is the high end (while random.randint(10, 1) causes an error).

However, rather than through their position, keyword arguments are identified by the keyword put before them in the function call. Keyword arguments are often used for optional parameters . For example, the print() function has the optional parameters end and sep to specify what should be printed at the end of its arguments and between its arguments (separating them), respectively.

If you ran a program with the following code:

print('Hello')
print('World')

the output would look like this:

Hello
World

The two outputted strings appear on separate lines because the print() function automatically adds a newline character to the end of the string it is passed. However, you can set the end keyword argument to change the newline character to a different string. For example, if the code were this:

print('Hello', end='')
print('World')

the output would look like this:

HelloWorld

The output is printed on a single line because there is no longer a newline printed after 'Hello' . Instead, the blank string is printed. This is useful if you need to disable the newline that gets added to the end of every print() function call.

Similarly, when you pass multiple string values to print() , the function will automatically separate them with a single space. Enter the following into the interactive shell:

>>> print('cats', 'dogs', 'mice')
cats dogs mice

But you could replace the default separating string by passing the sep keyword argument a different string. Enter the following into the interactive shell:

>>> print('cats', 'dogs', 'mice', sep=',')
cats,dogs,mice

You can add keyword arguments to the functions you write as well, but first you'll have to learn about the list and dictionary data types in the next two chapters. For now, just know that some functions have optional keyword arguments that can be specified when the function is called.

The Call Stack

Imagine that you have a meandering conversation with someone. You talk about your friend Alice, which then reminds you of a story about your coworker Bob, but first you have to explain something about your cousin Carol. You finish you story about Carol and go back to talking about Bob, and when you finish your story about Bob, you go back to talking about Alice. But then you are reminded about your brother David, so you tell a story about him, and then get back to finishing your original story about Alice. Your conversation followed a stack -like structure, like in Figure 3-1 . The conversation is stack-like because the current topic is always at the top of the stack.

Figure 3-1: Your meandering conversation stack

Similar to our meandering conversation, calling a function doesn't send the execution on a one-way trip to the top of a function. Python will remember which line of code called the function so that the execution can return there when it encounters a return statement. If that original function called other functions, the execution would return to those function calls first, before returning from the original function call.

Open a file editor window and enter the following code, saving it as abcdCallStack.py :

def a():
print('a() starts')
➊ b()
➋ d()
print('a() returns')

def b():
print('b() starts')
➌ c()
print('b() returns')

def c():
➍ print('c() starts')
print('c() returns')

def d():
print('d() starts')
print('d() returns')

➎ a()

If you run this program, the output will look like this:

a() starts
b() starts
c() starts
c() returns
b() returns
d() starts
d() returns
a() returns

You can view the execution of this program at https://autbor.com/abcdcallstack/ . When a() is called ➎ , it calls b() ➊ , which in turn calls c() ➌ . The c() function doesn't call anything; it just displays c() starts ➍ and c() returns before returning to the line in b() that called it ➌ . Once execution returns to the code in b() that called c() , it returns to the line in a() that called b() ➊ . The execution continues to the next line in the b() function ➋ , which is a call to d() . Like the c() function, the d() function also doesn't call anything. It just displays d() starts and d() returns before returning to the line in b() that called it. Since b() contains no other code, the execution returns to the line in a() that called b() ➋ . The last line in a() displays a() returns before returning to the original a() call at the end of the program ➎ .

The call stack is how Python remembers where to return the execution after each function call. The call stack isn't stored in a variable in your program; rather, Python handles it behind the scenes. When your program calls a function, Python creates a frame object on the top of the call stack. Frame objects store the line number of the original function call so that Python can remember where to return. If another function call is made, Python puts another frame object on the call stack above the other one.

When a function call returns, Python removes a frame object from the top of the stack and moves the execution to the line number stored in it. Note that frame objects are always added and removed from the top of the stack and not from any other place. Figure 3-2 illustrates the state of the call stack in abcdCallStack.py as each function is called and returns.

image

Figure 3-2: The frame objects of the call stack as abcdCallStack.py calls and returns from functions

The top of the call stack is which function the execution is currently in. When the call stack is empty, the execution is on a line outside of all functions.

The call stack is a technical detail that you don't strictly need to know about to write programs. It's enough to understand that function calls return to the line number they were called from. However, understanding call stacks makes it easier to understand local and global scopes, described in the next section.

Local and Global Scope

Parameters and variables that are assigned in a called function are said to exist in that function's local scope . Variables that are assigned outside all functions are said to exist in the global scope . A variable that exists in a local scope is called a local variable , while a variable that exists in the global scope is called a global variable . A variable must be one or the other; it cannot be both local and global.

Think of a scope as a container for variables. When a scope is destroyed, all the values stored in the scope's variables are forgotten. There is only one global scope, and it is created when your program begins. When your program terminates, the global scope is destroyed, and all its variables are forgotten. Otherwise, the next time you ran a program, the variables would remember their values from the last time you ran it.

A local scope is created whenever a function is called. Any variables assigned in the function exist within the function's local scope. When the function returns, the local scope is destroyed, and these variables are forgotten. The next time you call the function, the local variables will not remember the values stored in them from the last time the function was called. Local variables are also stored in frame objects on the call stack.

Scopes matter for several reasons:

The reason Python has different scopes instead of just making everything a global variable is so that when variables are modified by the code in a particular call to a function, the function interacts with the rest of the program only through its parameters and the return value. This narrows down the number of lines of code that may be causing a bug. If your program contained nothing but global variables and had a bug because of a variable being set to a bad value, then it would be hard to track down where this bad value was set. It could have been set from anywhere in the program, and your program could be hundreds or thousands of lines long! But if the bug is caused by a local variable with a bad value, you know that only the code in that one function could have set it incorrectly.

While using global variables in small programs is fine, it is a bad habit to rely on global variables as your programs get larger and larger.

Local Variables Cannot Be Used in the Global Scope

Consider this program, which will cause an error when you run it:

def spam():
➊ eggs = 31337
spam()
print(eggs)

If you run this program, the output will look like this:

Traceback (most recent call last):
File "C:/test1.py", line 4, in <module>
print(eggs)
NameError: name 'eggs' is not defined

The error happens because the eggs variable exists only in the local scope created when spam() is called ➊ . Once the program execution returns from spam , that local scope is destroyed, and there is no longer a variable named eggs . So when your program tries to run print(eggs) , Python gives you an error saying that eggs is not defined. This makes sense if you think about it; when the program execution is in the global scope, no local scopes exist, so there can't be any local variables. This is why only global variables can be used in the global scope.

Local Scopes Cannot Use Variables in Other Local Scopes

A new local scope is created whenever a function is called, including when a function is called from another function. Consider this program:

def spam():
➊ eggs = 99
➋ bacon()
➌ print(eggs)

def bacon():
ham = 101
➍ eggs = 0

➎ spam()

You can view the execution of this program at https://autbor.com/otherlocalscopes/ . When the program starts, the spam() function is called ➎ , and a local scope is created. The local variable eggs ➊ is set to 99 . Then the bacon() function is called ➋ , and a second local scope is created. Multiple local scopes can exist at the same time. In this new local scope, the local variable ham is set to 101 , and a local variable eggs -- which is different from the one in spam() 's local scope -- is also created ➍ and set to 0 .

When bacon() returns, the local scope for that call is destroyed, including its eggs variable. The program execution continues in the spam() function to print the value of eggs ➌ . Since the local scope for the call to spam() still exists, the only eggs variable is the spam() function's eggs variable, which was set to 99 . This is what the program prints.

The upshot is that local variables in one function are completely separate from the local variables in another function.

Global Variables Can Be Read from a Local Scope

Consider the following program:

def spam():
print(eggs)
eggs = 42
spam()
print(eggs)

You can view the execution of this program at https://autbor.com/readglobal/ . Since there is no parameter named eggs or any code that assigns eggs a value in the spam() function, when eggs is used in spam() , Python considers it a reference to the global variable eggs . This is why 42 is printed when the previous program is run.

Local and Global Variables with the Same Name

Technically, it's perfectly acceptable to use the same variable name for a global variable and local variables in different scopes in Python. But, to simplify your life, avoid doing this. To see what happens, enter the following code into the file editor and save it as localGlobalSameName.py :

def spam():
➊ eggs = 'spam local'
print(eggs) # prints 'spam local'

def bacon():
➋ eggs = 'bacon local'
print(eggs) # prints 'bacon local'
spam()
print(eggs) # prints 'bacon local'

➌ eggs = 'global'
bacon()
print(eggs) # prints 'global'

When you run this program, it outputs the following:

bacon local
spam local
bacon local
global

You can view the execution of this program at https://autbor.com/localglobalsamename/ . There are actually three different variables in this program, but confusingly they are all named eggs . The variables are as follows:

➊ A variable named eggs that exists in a local scope when spam() is called.

➋ A variable named eggs that exists in a local scope when bacon() is called.

➌ A variable named eggs that exists in the global scope.

Since these three separate variables all have the same name, it can be confusing to keep track of which one is being used at any given time. This is why you should avoid using the same variable name in different scopes.

The global Statement

If you need to modify a global variable from within a function, use the global statement. If you have a line such as global eggs at the top of a function, it tells Python, "In this function, eggs refers to the global variable, so don't create a local variable with this name." For example, enter the following code into the file editor and save it as globalStatement.py :

def spam():
➊ global eggs
➋ eggs = 'spam'

eggs = 'global'
spam()
print(eggs)

When you run this program, the final print() call will output this:

spam

You can view the execution of this program at https://autbor.com/globalstatement/ . Because eggs is declared global at the top of spam() ➊ , when eggs is set to 'spam' ➋ , this assignment is done to the globally scoped eggs . No local eggs variable is created.

There are four rules to tell whether a variable is in a local scope or global scope:

To get a better feel for these rules, here's an example program. Enter the following code into the file editor and save it as sameNameLocalGlobal.py :

def spam():
➊ global eggs
eggs = 'spam' # this is the global

def bacon():
➋ eggs = 'bacon' # this is a local

def ham():
➌ print(eggs) # this is the global

eggs = 42 # this is the global
spam()
print(eggs)

In the spam() function, eggs is the global eggs variable because there's a global statement for eggs at the beginning of the function ➊ . In bacon() , eggs is a local variable because there's an assignment statement for it in that function ➋ . In ham() ➌ , eggs is the global variable because there is no assignment statement or global statement for it in that function. If you run sameNameLocalGlobal.py , the output will look like this:

spam

You can view the execution of this program at https://autbor.com/sameNameLocalGlobal/ . In a function, a variable will either always be global or always be local. The code in a function can't use a local variable named eggs and then use the global eggs variable later in that same function.

NOTE

If you ever want to modify the value stored in a global variable from in a function, you must use a global statement on that variable.

If you try to use a local variable in a function before you assign a value to it, as in the following program, Python will give you an error. To see this, enter the following into the file editor and save it as sameNameError.py :

def spam():
print(eggs) # ERROR!
➊ eggs = 'spam local'

➋ eggs = 'global'
spam()

If you run the previous program, it produces an error message.

Traceback (most recent call last):
File "C:/sameNameError.py", line 6, in <module>
spam()
File "C:/sameNameError.py", line 2, in spam
print(eggs) # ERROR!
UnboundLocalError: local variable 'eggs' referenced before assignment

You can view the execution of this program at https://autbor.com/sameNameError/ . This error happens because Python sees that there is an assignment statement for eggs in the spam() function ➊ and, therefore, considers eggs to be local. But because print(eggs) is executed before eggs is assigned anything, the local variable eggs doesn't exist. Python will not fall back to using the global eggs variable ➋ .

FUNCTIONS AS "BLACK BOXES"

Often, all you need to know about a function are its inputs (the parameters) and output value; you don't always have to burden yourself with how the function's code actually works. When you think about functions in this high-level way, it's common to say that you're treating a function as a "black box."

This idea is fundamental to modern programming. Later chapters in this book will show you several modules with functions that were written by other people. While you can take a peek at the source code if you're curious, you don't need to know how these functions work in order to use them. And because writing functions without global variables is encouraged, you usually don't have to worry about the function's code interacting with the rest of your program. Exception Handling

Right now, getting an error, or exception , in your Python program means the entire program will crash. You don't want this to happen in real-world programs. Instead, you want the program to detect errors, handle them, and then continue to run.

For example, consider the following program, which has a divide-by-zero error. Open a file editor window and enter the following code, saving it as zeroDivide.py :

def spam(divideBy):
return 42 / divideBy

print(spam(2))
print(spam(12))
print(spam(0))
print(spam(1))

We've defined a function called spam , given it a parameter, and then printed the value of that function with various parameters to see what happens. This is the output you get when you run the previous code:

21.0
3.5
Traceback (most recent call last):
File "C:/zeroDivide.py", line 6, in <module>
print(spam(0))
File "C:/zeroDivide.py", line 2, in spam
return 42 / divideBy
ZeroDivisionError: division by zero

You can view the execution of this program at https://autbor.com/zerodivide/ . A ZeroDivisionError happens whenever you try to divide a number by zero. From the line number given in the error message, you know that the return statement in spam() is causing an error.

Errors can be handled with try and except statements. The code that could potentially have an error is put in a try clause. The program execution moves to the start of a following except clause if an error happens.

You can put the previous divide-by-zero code in a try clause and have an except clause contain code to handle what happens when this error occurs.

def spam(divideBy):
try:
return 42 / divideBy
except ZeroDivisionError:
print('Error: Invalid argument.')

print(spam(2))
print(spam(12))
print(spam(0))
print(spam(1))

When code in a try clause causes an error, the program execution immediately moves to the code in the except clause. After running that code, the execution continues as normal. The output of the previous program is as follows:

21.0
3.5
Error: Invalid argument.
None
42.0

You can view the execution of this program at https://autbor.com/tryexceptzerodivide/ . Note that any errors that occur in function calls in a try block will also be caught. Consider the following program, which instead has the spam() calls in the try block:

def spam(divideBy):
return 42 / divideBy

try:
print(spam(2))
print(spam(12))
print(spam(0))
print(spam(1))
except ZeroDivisionError:
print('Error: Invalid argument.')

When this program is run, the output looks like this:

21.0
3.5
Error: Invalid argument.

You can view the execution of this program at https://autbor.com/spamintry/ . The reason print(spam(1)) is never executed is because once the execution jumps to the code in the except clause, it does not return to the try clause. Instead, it just continues moving down the program as normal.

A Short Program: Zigzag

Let's use the programming concepts you've learned so far to create a small animation program. This program will create a back-and-forth, zigzag pattern until the user stops it by pressing the Mu editor's Stop button or by pressing CTRL-C . When you run this program, the output will look something like this:

********
********
********
********
********
********
********
********
********

Type the following source code into the file editor, and save the file as zigzag.py :

import time, sys
indent = 0 # How many spaces to indent.
indentIncreasing = True # Whether the indentation is increasing or not.

try:
while True: # The main program loop.
print(' ' * indent, end='')
print('********')
time.sleep(0.1) # Pause for 1/10 of a second.

if indentIncreasing:
# Increase the number of spaces:
indent = indent + 1
if indent == 20:
# Change direction:
indentIncreasing = False

else:
# Decrease the number of spaces:
indent = indent - 1
if indent == 0:
# Change direction:
indentIncreasing = True
except KeyboardInterrupt:
sys.exit()

Let's look at this code line by line, starting at the top.

import time, sys
indent = 0 # How many spaces to indent.
indentIncreasing = True # Whether the indentation is increasing or not.

First, we'll import the time and sys modules. Our program uses two variables: the indent variable keeps track of how many spaces of indentation are before the band of eight asterisks and indentIncreasing contains a Boolean value to determine if the amount of indentation is increasing or decreasing.

try:
while True: # The main program loop.
print(' ' * indent, end='')
print('********')
time.sleep(0.1) # Pause for 1/10 of a second.

Next, we place the rest of the program inside a try statement. When the user presses CTRL-C while a Python program is running, Python raises the KeyboardInterrupt exception. If there is no try - except statement to catch this exception, the program crashes with an ugly error message. However, for our program, we want it to cleanly handle the KeyboardInterrupt exception by calling sys.exit() . (The code for this is in the except statement at the end of the program.)

The while True: infinite loop will repeat the instructions in our program forever. This involves using ' ' * indent to print the correct amount of spaces of indentation. We don't want to automatically print a newline after these spaces, so we also pass end='' to the first print() call. A second print() call prints the band of asterisks. The time.sleep() function hasn't been covered yet, but suffice it to say that it introduces a one-tenth-second pause in our program at this point.

if indentIncreasing:
# Increase the number of spaces:
indent = indent + 1
if indent == 20:
indentIncreasing = False # Change direction.

Next, we want to adjust the amount of indentation for the next time we print asterisks. If indentIncreasing is True , then we want to add one to indent . But once indent reaches 20 , we want the indentation to decrease.

else:
# Decrease the number of spaces:
indent = indent - 1
if indent == 0:
indentIncreasing = True # Change direction.

Meanwhile, if indentIncreasing was False , we want to subtract one from indent . Once indent reaches 0 , we want the indentation to increase once again. Either way, the program execution will jump back to the start of the main program loop to print the asterisks again.

except KeyboardInterrupt:
sys.exit()

If the user presses CTRL-C at any point that the program execution is in the try block, the KeyboardInterrrupt exception is raised and handled by this except statement. The program execution moves inside the except block, which runs sys.exit() and quits the program. This way, even though the main program loop is an infinite loop, the user has a way to shut down the program.

Summary

Functions are the primary way to compartmentalize your code into logical groups. Since the variables in functions exist in their own local scopes, the code in one function cannot directly affect the values of variables in other functions. This limits what code could be changing the values of your variables, which can be helpful when it comes to debugging your code.

Functions are a great tool to help you organize your code. You can think of them as black boxes: they have inputs in the form of parameters and outputs in the form of return values, and the code in them doesn't affect variables in other functions.

In previous chapters, a single error could cause your programs to crash. In this chapter, you learned about try and except statements, which can run code when an error has been detected. This can make your programs more resilient to common error cases.

Practice Questions

1 . Why are functions advantageous to have in your programs?

2 . When does the code in a function execute: when the function is defined or when the function is called?

3 . What statement creates a function?

4 . What is the difference between a function and a function call?

5 . How many global scopes are there in a Python program? How many local scopes?

6 . What happens to variables in a local scope when the function call returns?

7 . What is a return value? Can a return value be part of an expression?

8 . If a function does not have a return statement, what is the return value of a call to that function?

9 . How can you force a variable in a function to refer to the global variable?

10 . What is the data type of None ?

11 . What does the import areallyourpetsnamederic statement do?

12 . If you had a function named bacon() in a module named spam , how would you call it after importing spam ?

13 . How can you prevent a program from crashing when it gets an error?

14 . What goes in the try clause? What goes in the except clause?

[Nov 23, 2019] How can I remove a trailing newline?

Jan 01, 2008 | stackoverflow.com

Ask Question Asked 11 years ago Active 16 days ago Viewed 1.7m times


, 2008-11-08 18:25:24

What is the Python equivalent of Perl's chomp function, which removes the last character of a string if it is a newline?

9 revs, 7 users 37%
, 2017-05-11 19:54:59

Try the method rstrip() (see doc Python 2 and Python 3 )
>>> 'test string\n'.rstrip()
'test string'

Python's rstrip() method strips all kinds of trailing whitespace by default, not just one newline as Perl does with chomp .

>>> 'test string \n \r\n\n\r \n\n'.rstrip()
'test string'

To strip only newlines:

>>> 'test string \n \r\n\n\r \n\n'.rstrip('\n')
'test string \n \r\n\n\r '

There are also the methods lstrip() and strip() :

>>> s = "   \n\r\n  \n  abc   def \n\r\n  \n  "
>>> s.strip()
'abc   def'
>>> s.lstrip()
'abc   def \n\r\n  \n  '
>>> s.rstrip()
'   \n\r\n  \n  abc   def'

Ryan Ginstrom , 2008-11-09 05:52:43

And I would say the "pythonic" way to get lines without trailing newline characters is splitlines().
>>> text = "line 1\nline 2\r\nline 3\nline 4"
>>> text.splitlines()
['line 1', 'line 2', 'line 3', 'line 4']

Mike ,

The canonical way to strip end-of-line (EOL) characters is to use the string rstrip() method removing any trailing \r or \n. Here are examples for Mac, Windows, and Unix EOL characters.
>>> 'Mac EOL\r'.rstrip('\r\n')
'Mac EOL'
>>> 'Windows EOL\r\n'.rstrip('\r\n')
'Windows EOL'
>>> 'Unix EOL\n'.rstrip('\r\n')
'Unix EOL'

Using '\r\n' as the parameter to rstrip means that it will strip out any trailing combination of '\r' or '\n'. That's why it works in all three cases above.

This nuance matters in rare cases. For example, I once had to process a text file which contained an HL7 message. The HL7 standard requires a trailing '\r' as its EOL character. The Windows machine on which I was using this message had appended its own '\r\n' EOL character. Therefore, the end of each line looked like '\r\r\n'. Using rstrip('\r\n') would have taken off the entire '\r\r\n' which is not what I wanted. In that case, I simply sliced off the last two characters instead.

Note that unlike Perl's chomp function, this will strip all specified characters at the end of the string, not just one:

>>> "Hello\n\n\n".rstrip("\n")
"Hello"

, 2008-11-28 17:31:34

Note that rstrip doesn't act exactly like Perl's chomp() because it doesn't modify the string. That is, in Perl:
$x="a\n";

chomp $x

results in $x being "a" .

but in Python:

x="a\n"

x.rstrip()

will mean that the value of x is still "a\n" . Even x=x.rstrip() doesn't always give the same result, as it strips all whitespace from the end of the string, not just one newline at most.

Jamie ,

I might use something like this:
import os
s = s.rstrip(os.linesep)

I think the problem with rstrip("\n") is that you'll probably want to make sure the line separator is portable. (some antiquated systems are rumored to use "\r\n" ). The other gotcha is that rstrip will strip out repeated whitespace. Hopefully os.linesep will contain the right characters. the above works for me.

kiriloff , 2013-05-13 16:41:22

You may use line = line.rstrip('\n') . This will strip all newlines from the end of the string, not just one.

slec , 2015-03-09 08:02:55

s = s.rstrip()

will remove all newlines at the end of the string s . The assignment is needed because rstrip returns a new string instead of modifying the original string.

Alien Life Form ,

This would replicate exactly perl's chomp (minus behavior on arrays) for "\n" line terminator:
def chomp(x):
    if x.endswith("\r\n"): return x[:-2]
    if x.endswith("\n") or x.endswith("\r"): return x[:-1]
    return x

(Note: it does not modify string 'in place'; it does not strip extra trailing whitespace; takes \r\n in account)

Hackaholic ,

you can use strip:
line = line.strip()

demo:

>>> "\n\n hello world \n\n".strip()
'hello world'

mihaicc ,

"line 1\nline 2\r\n...".replace('\n', '').replace('\r', '')
>>> 'line 1line 2...'

or you could always get geekier with regexps :)

have fun!

Carlos Valiente , 2011-04-27 11:43:20

Careful with "foo".rstrip(os.linesep) : That will only chomp the newline characters for the platform where your Python is being executed. Imagine you're chimping the lines of a Windows file under Linux, for instance:
$ python
Python 2.7.1 (r271:86832, Mar 18 2011, 09:09:48) 
[GCC 4.5.0 20100604 [gcc-4_5-branch revision 160292]] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os, sys
>>> sys.platform
'linux2'
>>> "foo\r\n".rstrip(os.linesep)
'foo\r'
>>>

Use "foo".rstrip("\r\n") instead, as Mike says above.

minopret , 2013-10-23 01:32:11

An example in Python's documentation simply uses line.strip() .

Perl's chomp function removes one linebreak sequence from the end of a string only if it's actually there.

Here is how I plan to do that in Python, if process is conceptually the function that I need in order to do something useful to each line from this file:

import os
sep_pos = -len(os.linesep)
with open("file.txt") as f:
    for line in f:
        if line[sep_pos:] == os.linesep:
            line = line[:sep_pos]
        process(line)

ingydotnet ,

rstrip doesn't do the same thing as chomp, on so many levels. Read http://perldoc.perl.org/functions/chomp.html and see that chomp is very complex indeed.

However, my main point is that chomp removes at most 1 line ending, whereas rstrip will remove as many as it can.

Here you can see rstrip removing all the newlines:

>>> 'foo\n\n'.rstrip(os.linesep)
'foo'

A much closer approximation of typical Perl chomp usage can be accomplished with re.sub, like this:

>>> re.sub(os.linesep + r'\Z','','foo\n\n')
'foo\n'

Andrew Grimm ,

I don't program in Python, but I came across an FAQ at python.org advocating S.rstrip("\r\n") for python 2.2 or later.

, 2014-01-20 19:07:03

import re

r_unwanted = re.compile("[\n\t\r]")
r_unwanted.sub("", your_text)

Leozj ,

If your question is to clean up all the line breaks in a multiple line str object (oldstr), you can split it into a list according to the delimiter '\n' and then join this list into a new str(newstr).

newstr = "".join(oldstr.split('\n'))

kuzzooroo ,

I find it convenient to have be able to get the chomped lines via in iterator, parallel to the way you can get the un-chomped lines from a file object. You can do so with the following code:
def chomped_lines(it):
    return map(operator.methodcaller('rstrip', '\r\n'), it)

Sample usage:

with open("file.txt") as infile:
    for line in chomped_lines(infile):
        process(line)

Chij , 2011-11-30 14:04:19

workaround solution for special case:

if the newline character is the last character (as is the case with most file inputs), then for any element in the collection you can index as follows:

foobar= foobar[:-1]

to slice out your newline character.

user3780389 , 2017-04-26 17:58:16

It looks like there is not a perfect analog for perl's chomp . In particular, rstrip cannot handle multi-character newline delimiters like \r\n . However, splitlines does as pointed out here . Following my answer on a different question, you can combine join and splitlines to remove/replace all newlines from a string s :
''.join(s.splitlines())

The following removes exactly one trailing newline (as chomp would, I believe). Passing True as the keepends argument to splitlines retain the delimiters. Then, splitlines is called again to remove the delimiters on just the last "line":

def chomp(s):
    if len(s):
        lines = s.splitlines(True)
        last = lines.pop()
        return ''.join(lines + last.splitlines())
    else:
        return ''

Taylor Edmiston ,

I'm bubbling up my regular expression based answer from one I posted earlier in the comments of another answer. I think using re is a clearer more explicit solution to this problem than str.rstrip .
>>> import re

If you want to remove one or more trailing newline chars:

>>> re.sub(r'[\n\r]+$', '', '\nx\r\n')
'\nx'

If you want to remove newline chars everywhere (not just trailing):

>>> re.sub(r'[\n\r]+', '', '\nx\r\n')
'x'

If you want to remove only 1-2 trailing newline chars (i.e., \r , \n , \r\n , \n\r , \r\r , \n\n )

>>> re.sub(r'[\n\r]{1,2}$', '', '\nx\r\n\r\n')
'\nx\r'
>>> re.sub(r'[\n\r]{1,2}$', '', '\nx\r\n\r')
'\nx\r'
>>> re.sub(r'[\n\r]{1,2}$', '', '\nx\r\n')
'\nx'

I have a feeling what most people really want here, is to remove just one occurrence of a trailing newline character, either \r\n or \n and nothing more.

>>> re.sub(r'(?:\r\n|\n)$', '', '\nx\n\n', count=1)
'\nx\n'
>>> re.sub(r'(?:\r\n|\n)$', '', '\nx\r\n\r\n', count=1)
'\nx\r\n'
>>> re.sub(r'(?:\r\n|\n)$', '', '\nx\r\n', count=1)
'\nx'
>>> re.sub(r'(?:\r\n|\n)$', '', '\nx\n', count=1)
'\nx'

(The ?: is to create a non-capturing group.)

(By the way this is not what '...'.rstrip('\n', '').rstrip('\r', '') does which may not be clear to others stumbling upon this thread. str.rstrip strips as many of the trailing characters as possible, so a string like foo\n\n\n would result in a false positive of foo whereas you may have wanted to preserve the other newlines after stripping a single trailing one.)

Help me , 2016-05-20 12:29:21

Just use :
line = line.rstrip("\n")

or

line = line.strip("\n")

You don't need any of this complicated stuff

, 2016-11-22 18:30:37

>>> '   spacious   '.rstrip()
'   spacious'
>>> "AABAA".rstrip("A")
  'AAB'
>>> "ABBA".rstrip("AB") # both AB and BA are stripped
   ''
>>> "ABCABBA".rstrip("AB")
   'ABC'

internetional , 2016-11-22 20:17:58

There are three types of line endings that we normally encounter: \n , \r and \r\n . A rather simple regular expression in re.sub , namely r"\r?\n?$" , is able to catch them all.

(And we gotta catch 'em all , am I right?)

import re

re.sub(r"\r?\n?$", "", the_text, 1)

With the last argument, we limit the number of occurences replaced to one, mimicking chomp to some extent. Example:

import re

text_1 = "hellothere\n\n\n"
text_2 = "hellothere\n\n\r"
text_3 = "hellothere\n\n\r\n"

a = re.sub(r"\r?\n?$", "", text_1, 1)
b = re.sub(r"\r?\n?$", "", text_2, 1)
c = re.sub(r"\r?\n?$", "", text_3, 1)

... where a == b == c is True .

Venfah Nazir , 2018-06-15 07:24:21


This will work both for windows and linux (bit expensive with re sub if you are looking for only re solution)

import re 
if re.search("(\\r|)\\n$", line):
    line = re.sub("(\\r|)\\n$", "", line)

Stephen Miller ,

If you are concerned about speed (say you have a looong list of strings) and you know the nature of the newline char, string slicing is actually faster than rstrip. A little test to illustrate this:
import time

loops = 50000000

def method1(loops=loops):
    test_string = 'num\n'
    t0 = time.time()
    for num in xrange(loops):
        out_sting = test_string[:-1]
    t1 = time.time()
    print('Method 1: ' + str(t1 - t0))

def method2(loops=loops):
    test_string = 'num\n'
    t0 = time.time()
    for num in xrange(loops):
        out_sting = test_string.rstrip()
    t1 = time.time()
    print('Method 2: ' + str(t1 - t0))

method1()
method2()

Output:

Method 1: 3.92700004578
Method 2: 6.73000001907

sim , 2019-10-22 07:43:27

s = '''Hello  World \t\n\r\tHi There'''
# import the module string   
import string
# use the method translate to convert 
s.translate({ord(c): None for c in string.whitespace}
>>'HelloWorldHiThere'

With regex

s = '''  Hello  World 
\t\n\r\tHi '''
print(re.sub(r"\s+", "", s), sep='')  # \s matches all white spaces
>HelloWorldHi

Replace \n,\t,\r

s.replace('\n', '').replace('\t','').replace('\r','')
>'  Hello  World Hi '

With regex

s = '''Hello  World \t\n\r\tHi There'''
regex = re.compile(r'[\n\r\t]')
regex.sub("", s)
>'Hello  World Hi There'

with Join

s = '''Hello  World \t\n\r\tHi There'''
' '.join(s.split())
>'Hello  World Hi There'

DeepBlue , 2019-11-06 20:50:30

First split lines then join them by any separator you like.
  x = ' '.join(x.splitlines())

should work like a charm.

user4178860 , 2014-10-24 18:34:12

A catch all:
line = line.rstrip('\r|\n')

Flimm , 2016-06-30 16:20:15

rstrip does not take regular expression. "hi|||\n\n".rstrip("\r|\n") returns "hi"Flimm Jun 30 '16 at 16:20

[Nov 22, 2019] Using global variables in a function

Jan 01, 2009 | stackoverflow.com

user46646 , 2009-01-08 05:45:02

How can I create or use a global variable in a function?

If I create a global variable in one function, how can I use that global variable in another function? Do I need to store the global variable in a local variable of the function which needs its access?

Paul Stephenson , 2009-01-08 08:39:44

You can use a global variable in other functions by declaring it as global in each function that assigns to it:
globvar = 0

def set_globvar_to_one():
    global globvar    # Needed to modify global copy of globvar
    globvar = 1

def print_globvar():
    print(globvar)     # No need for global declaration to read value of globvar

set_globvar_to_one()
print_globvar()       # Prints 1

I imagine the reason for it is that, since global variables are so dangerous, Python wants to make sure that you really know that's what you're playing with by explicitly requiring the global keyword.

See other answers if you want to share a global variable across modules.

Jeff Shannon , 2009-01-08 09:19:55

If I'm understanding your situation correctly, what you're seeing is the result of how Python handles local (function) and global (module) namespaces.

Say you've got a module like this:

# sample.py
myGlobal = 5

def func1():
    myGlobal = 42

def func2():
    print myGlobal

func1()
func2()

You might expecting this to print 42, but instead it prints 5. As has already been mentioned, if you add a ' global ' declaration to func1() , then func2() will print 42.

def func1():
    global myGlobal
    myGlobal = 42

What's going on here is that Python assumes that any name that is assigned to , anywhere within a function, is local to that function unless explicitly told otherwise. If it is only reading from a name, and the name doesn't exist locally, it will try to look up the name in any containing scopes (e.g. the module's global scope).

When you assign 42 to the name myGlobal , therefore, Python creates a local variable that shadows the global variable of the same name. That local goes out of scope and is garbage-collected when func1() returns; meanwhile, func2() can never see anything other than the (unmodified) global name. Note that this namespace decision happens at compile time, not at runtime -- if you were to read the value of myGlobal inside func1() before you assign to it, you'd get an UnboundLocalError , because Python has already decided that it must be a local variable but it has not had any value associated with it yet. But by using the ' global ' statement, you tell Python that it should look elsewhere for the name instead of assigning to it locally.

(I believe that this behavior originated largely through an optimization of local namespaces -- without this behavior, Python's VM would need to perform at least three name lookups each time a new name is assigned to inside a function (to ensure that the name didn't already exist at module/builtin level), which would significantly slow down a very common operation.)

gimel , 2009-01-08 05:59:04

You may want to explore the notion of namespaces . In Python, the module is the natural place for global data:

Each module has its own private symbol table, which is used as the global symbol table by all functions defined in the module. Thus, the author of a module can use global variables in the module without worrying about accidental clashes with a user's global variables. On the other hand, if you know what you are doing you can touch a module's global variables with the same notation used to refer to its functions, modname.itemname .

A specific use of global-in-a-module is described here - How do I share global variables across modules? , and for completeness the contents are shared here:

The canonical way to share information across modules within a single program is to create a special configuration module (often called config or cfg ). Just import the configuration module in all modules of your application; the module then becomes available as a global name. Because there is only one instance of each module, any changes made to the module object get reflected everywhere. For example:

File: config.py

x = 0   # Default value of the 'x' configuration setting

File: mod.py

import config
config.x = 1

File: main.py

import config
import mod
print config.x

SingleNegationElimination ,

Python uses a simple heuristic to decide which scope it should load a variable from, between local and global. If a variable name appears on the left hand side of an assignment, but is not declared global, it is assumed to be local. If it does not appear on the left hand side of an assignment, it is assumed to be global.
>>> import dis
>>> def foo():
...     global bar
...     baz = 5
...     print bar
...     print baz
...     print quux
... 
>>> dis.disassemble(foo.func_code)
  3           0 LOAD_CONST               1 (5)
              3 STORE_FAST               0 (baz)

  4           6 LOAD_GLOBAL              0 (bar)
              9 PRINT_ITEM          
             10 PRINT_NEWLINE       

  5          11 LOAD_FAST                0 (baz)
             14 PRINT_ITEM          
             15 PRINT_NEWLINE       

  6          16 LOAD_GLOBAL              1 (quux)
             19 PRINT_ITEM          
             20 PRINT_NEWLINE       
             21 LOAD_CONST               0 (None)
             24 RETURN_VALUE        
>>>

See how baz, which appears on the left side of an assignment in foo() , is the only LOAD_FAST variable.

J S , 2009-01-08 09:03:33

If you want to refer to a global variable in a function, you can use the global keyword to declare which variables are global. You don't have to use it in all cases (as someone here incorrectly claims) - if the name referenced in an expression cannot be found in local scope or scopes in the functions in which this function is defined, it is looked up among global variables.

However, if you assign to a new variable not declared as global in the function, it is implicitly declared as local, and it can overshadow any existing global variable with the same name.

Also, global variables are useful, contrary to some OOP zealots who claim otherwise - especially for smaller scripts, where OOP is overkill.

Rauni Lillemets ,

In addition to already existing answers and to make this more confusing:

In Python, variables that are only referenced inside a function are implicitly global . If a variable is assigned a new value anywhere within the function's body, it's assumed to be a local . If a variable is ever assigned a new value inside the function, the variable is implicitly local, and you need to explicitly declare it as 'global'.

Though a bit surprising at first, a moment's consideration explains this. On one hand, requiring global for assigned variables provides a bar against unintended side-effects. On the other hand, if global was required for all global references, you'd be using global all the time. You'd have to declare as global every reference to a built-in function or to a component of an imported module. This clutter would defeat the usefulness of the global declaration for identifying side-effects.

Source: What are the rules for local and global variables in Python? .

Aaron Hall ,

If I create a global variable in one function, how can I use that variable in another function?

We can create a global with the following function:

def create_global_variable():
    global global_variable # must declare it to be a global first
    # modifications are thus reflected on the module's global scope
    global_variable = 'Foo'

Writing a function does not actually run its code. So we call the create_global_variable function:

>>> create_global_variable()
Using globals without modification

You can just use it, so long as you don't expect to change which object it points to:

For example,

def use_global_variable():
    return global_variable + '!!!'

and now we can use the global variable:

>>> use_global_variable()
'Foo!!!'
Modification of the global variable from inside a function

To point the global variable at a different object, you are required to use the global keyword again:

def change_global_variable():
    global global_variable
    global_variable = 'Bar'

Note that after writing this function, the code actually changing it has still not run:

>>> use_global_variable()
'Foo!!!'

So after calling the function:

>>> change_global_variable()

we can see that the global variable has been changed. The global_variable name now points to 'Bar' :

>>> use_global_variable()
'Bar!!!'

Note that "global" in Python is not truly global - it's only global to the module level. So it is only available to functions written in the modules in which it is global. Functions remember the module in which they are written, so when they are exported into other modules, they still look in the module in which they were created to find global variables.

Local variables with the same name

If you create a local variable with the same name, it will overshadow a global variable:

def use_local_with_same_name_as_global():
    # bad name for a local variable, though.
    global_variable = 'Baz' 
    return global_variable + '!!!'

>>> use_local_with_same_name_as_global()
'Baz!!!'

But using that misnamed local variable does not change the global variable:

>>> use_global_variable()
'Bar!!!'

Note that you should avoid using the local variables with the same names as globals unless you know precisely what you are doing and have a very good reason to do so. I have not yet encountered such a reason.

Bohdan , 2013-10-03 05:41:16

With parallel execution, global variables can cause unexpected results if you don't understand what is happening. Here is an example of using a global variable within multiprocessing. We can clearly see that each process works with its own copy of the variable:
import multiprocessing
import os
import random
import sys
import time

def worker(new_value):
    old_value = get_value()
    set_value(random.randint(1, 99))
    print('pid=[{pid}] '
          'old_value=[{old_value:2}] '
          'new_value=[{new_value:2}] '
          'get_value=[{get_value:2}]'.format(
          pid=str(os.getpid()),
          old_value=old_value,
          new_value=new_value,
          get_value=get_value()))

def get_value():
    global global_variable
    return global_variable

def set_value(new_value):
    global global_variable
    global_variable = new_value

global_variable = -1

print('before set_value(), get_value() = [%s]' % get_value())
set_value(new_value=-2)
print('after  set_value(), get_value() = [%s]' % get_value())

processPool = multiprocessing.Pool(processes=5)
processPool.map(func=worker, iterable=range(15))

Output:

before set_value(), get_value() = [-1]
after  set_value(), get_value() = [-2]
pid=[53970] old_value=[-2] new_value=[ 0] get_value=[23]
pid=[53971] old_value=[-2] new_value=[ 1] get_value=[42]
pid=[53970] old_value=[23] new_value=[ 4] get_value=[50]
pid=[53970] old_value=[50] new_value=[ 6] get_value=[14]
pid=[53971] old_value=[42] new_value=[ 5] get_value=[31]
pid=[53972] old_value=[-2] new_value=[ 2] get_value=[44]
pid=[53973] old_value=[-2] new_value=[ 3] get_value=[94]
pid=[53970] old_value=[14] new_value=[ 7] get_value=[21]
pid=[53971] old_value=[31] new_value=[ 8] get_value=[34]
pid=[53972] old_value=[44] new_value=[ 9] get_value=[59]
pid=[53973] old_value=[94] new_value=[10] get_value=[87]
pid=[53970] old_value=[21] new_value=[11] get_value=[21]
pid=[53971] old_value=[34] new_value=[12] get_value=[82]
pid=[53972] old_value=[59] new_value=[13] get_value=[ 4]
pid=[53973] old_value=[87] new_value=[14] get_value=[70]

user2876408 ,

As it turns out the answer is always simple.

Here is a small sample module with a simple way to show it in a main definition:

def five(enterAnumber,sumation):
    global helper
    helper  = enterAnumber + sumation

def isTheNumber():
    return helper

Here is how to show it in a main definition:

import TestPy

def main():
    atest  = TestPy
    atest.five(5,8)
    print(atest.isTheNumber())

if __name__ == '__main__':
    main()

This simple code works just like that, and it will execute. I hope it helps.

gxyd , 2014-12-04 06:27:43

What you are saying is to use the method like this:
globvar = 5

def f():
    var = globvar
    print(var)

f()  # Prints 5

But the better way is to use the global variable like this:

globavar = 5
def f():
    global globvar
    print(globvar)
f()   #prints 5

Both give the same output.

Mohamed El-Saka , 2014-12-20 12:45:26

You need to reference the global variable in every function you want to use.

As follows:

var = "test"

def printGlobalText():
    global var #wWe are telling to explicitly use the global version
    var = "global from printGlobalText fun."
    print "var from printGlobalText: " + var

def printLocalText():
    #We are NOT telling to explicitly use the global version, so we are creating a local variable
    var = "local version from printLocalText fun"
    print "var from printLocalText: " + var

printGlobalText()
printLocalText()
"""
Output Result:
var from printGlobalText: global from printGlobalText fun.
var from printLocalText: local version from printLocalText
[Finished in 0.1s]
"""

Kylotan , 2009-01-09 11:56:19

You're not actually storing the global in a local variable, just creating a local reference to the same object that your original global reference refers to. Remember that pretty much everything in Python is a name referring to an object, and nothing gets copied in usual operation.

If you didn't have to explicitly specify when an identifier was to refer to a predefined global, then you'd presumably have to explicitly specify when an identifier is a new local variable instead (for example, with something like the 'var' command seen in JavaScript). Since local variables are more common than global variables in any serious and non-trivial system, Python's system makes more sense in most cases.

You could have a language which attempted to guess, using a global variable if it existed or creating a local variable if it didn't. However, that would be very error-prone. For example, importing another module could inadvertently introduce a global variable by that name, changing the behaviour of your program.

Sagar Mehta ,

Try this:
def x1():
    global x
    x = 6

def x2():
    global x
    x = x+1
    print x

x = 5
x1()
x2()  # output --> 7

Martin Thoma , 2017-04-07 18:52:13

In case you have a local variable with the same name, you might want to use the globals() function .
globals()['your_global_var'] = 42

, 2015-10-24 15:46:18

Following on and as an add on, use a file to contain all global variables all declared locally and then import as :

File initval.py :

Stocksin = 300
Prices = []

File getstocks.py :

import initval as iv

def getmystocks(): 
    iv.Stocksin = getstockcount()


def getmycharts():
    for ic in range(iv.Stocksin):

Mike Lampton , 2016-01-07 20:41:19

Writing to explicit elements of a global array does not apparently need the global declaration, though writing to it "wholesale" does have that requirement:
import numpy as np

hostValue = 3.14159
hostArray = np.array([2., 3.])
hostMatrix = np.array([[1.0, 0.0],[ 0.0, 1.0]])

def func1():
    global hostValue    # mandatory, else local.
    hostValue = 2.0

def func2():
    global hostValue    # mandatory, else UnboundLocalError.
    hostValue += 1.0

def func3():
    global hostArray    # mandatory, else local.
    hostArray = np.array([14., 15.])

def func4():            # no need for globals
    hostArray[0] = 123.4

def func5():            # no need for globals
    hostArray[1] += 1.0

def func6():            # no need for globals
    hostMatrix[1][1] = 12.

def func7():            # no need for globals
    hostMatrix[0][0] += 0.33

func1()
print "After func1(), hostValue = ", hostValue
func2()
print "After func2(), hostValue = ", hostValue
func3()
print "After func3(), hostArray = ", hostArray
func4()
print "After func4(), hostArray = ", hostArray
func5()
print "After func5(), hostArray = ", hostArray
func6()
print "After func6(), hostMatrix = \n", hostMatrix
func7()
print "After func7(), hostMatrix = \n", hostMatrix

Rafaël Dera ,

I'm adding this as I haven't seen it in any of the other answers and it might be useful for someone struggling with something similar. The globals() function returns a mutable global symbol dictionary where you can "magically" make data available for the rest of your code. For example:
from pickle import load
def loaditem(name):
    with open(r"C:\pickle\file\location"+"\{}.dat".format(name), "rb") as openfile:
        globals()[name] = load(openfile)
    return True

and

from pickle import dump
def dumpfile(name):
    with open(name+".dat", "wb") as outfile:
        dump(globals()[name], outfile)
    return True

Will just let you dump/load variables out of and into the global namespace. Super convenient, no muss, no fuss. Pretty sure it's Python 3 only.

llewellyn falco , 2017-08-19 08:48:27

Reference the class namespace where you want the change to show up.

In this example, runner is using max from the file config. I want my test to change the value of max when runner is using it.

main/config.py

max = 15000

main/runner.py

from main import config
def check_threads():
    return max < thread_count

tests/runner_test.py

from main import runner                # <----- 1. add file
from main.runner import check_threads
class RunnerTest(unittest):
   def test_threads(self):
       runner.max = 0                  # <----- 2. set global 
       check_threads()

[Nov 21, 2019] You must add parentheses after a function name to call it

Nov 21, 2019 | archive.is

Always Use Parentheses to Call a Function You must add parentheses after a function name to call it, whether it takes arguments or not. That is, use function() , not function . Python functions are simply objects that have a special operation, a call, that you trigger with the parentheses. Like all objects, they can also be assigned to variables, and used indirectly: x = function; x() . In Python training, this seems to occur most often with files. It's common to see beginners type file.close to close a file, rather than file.close() ; because it's legal to reference a function without calling it, the first version without parenthesis succeeds silently, but does not close the file!

[Nov 21, 2019] Passing an Array/List into Python

Dec 17, 2017 | stackoverflow.com

JAL ,Dec 17, 2017 at 8:12

I've been looking at passing arrays, or lists, as Python tends to call them, into a function.

I read something about using *args, such as:

def someFunc(*args)
    for x in args
        print x

But not sure if this is right/wrong. Nothing seems to work as I want. I'm used to be able to pass arrays into PHP function with ease and this is confusing me. It also seems I can't do this:

def someFunc(*args, someString)

As it throws up an error.

I think I've just got myself completely confused and looking for someone to clear it up for me.

Rafał Rawicki ,Feb 13 at 15:08

When you define your function using this syntax:
def someFunc(*args)
    for x in args
        print x

You're telling it that you expect a variable number of arguments. If you want to pass in a List (Array from other languages) you'd do something like this:

def someFunc(myList = [], *args)
    for x in myList:
        print x

Then you can call it with this:

items = [1,2,3,4,5]

someFunc(items)

You need to define named arguments before variable arguments, and variable arguments before keyword arguments. You can also have this:

def someFunc(arg1, arg2, arg3, *args, **kwargs)
    for x in args
        print x

Which requires at least three arguments, and supports variable numbers of other arguments and keyword arguments.

JoshD ,Oct 18, 2010 at 20:28

You can pass lists just like other types:
l = [1,2,3]

def stuff(a):
   for x in a:
      print a


stuff(l)

This prints the list l. Keep in mind lists are passed as references not as a deep copy.

Gintautas Miliauskas ,Oct 18, 2010 at 16:14

Python lists (which are not just arrays because their size can be changed on the fly) are normal Python objects and can be passed in to functions as any variable. The * syntax is used for unpacking lists, which is probably not something you want to do now.

,

You don't need to use the asterisk to accept a list.

Simply give the argument a name in the definition, and pass in a list like

def takes_list(a_list):
    for item in a_list:
         print item

[Nov 21, 2019] http://web.archive.org/web/20031002184114/www.amk.ca/python/writing/warts.html

Nov 21, 2019 | web.archive.org

Python has 3 built-in functions, map() , filter() , and reduce() , that provide some support for the functional style of programming. In versions of Python before 2.2, using these functions sometimes required a little hack with default arguments.

Let's choose one particular function for our example: filter(func, L) loops over the list L , returning a new list containing all the elements of L for which func(element) returned true. Take the situation where you have a list of numbers L , and want to find all the objects that are even numbers (multiples of 2). You could write this as:

L2 = filter(lambda N: (N % 2) == 0, L)

In case you're not familiar with the lambda statement: it's defining a little function without a name that takes a single parameter N and returns the value of the comparison expression.

L2 is then set to a list containing all of the even numbers in L :

>>> L = [0, 5, 4, 32.5, 17, -6]
>>> L2 = filter(lambda N: (N % 2) == 0, L)
>>> print L2
[0, 4, -6]
>>>

Now, what if we want to extend this so you can find all the multiples of a given number m ? In versions of Python up to 2.1, the rules for variable scoping would prevent the obvious code from working inside a function:

def f(L):
    m = 3
    L2 = filter(lambda N: (N % m) == 0, L)
    return L2

f([0, 2, 3, 17, -15])

On running this in Python 2.1, you would get a NameError for m in the second line of f() . Inside the anonymous function defined by the lambda statement, Python's scoping rules dictated that first the function's local variables and then the module-level variables were searched; f() 's local variables were never searched at all. The solution was to specify V as a default argument:

def f(L):
    m = 3
    L2 = filter(lambda N, m=m: (N % m) == 0, L)
    return L2

f([0, 2, 3, 17, -15])

If the filtering function required several of f() 's local variables, they'd all have to be passed in as default arguments. This results in the self=self, v=v that can be seen cluttering many uses of map() and filter() . Fixing this required modifying Python's scoping rules.

Python 2.1 added static scoping to the language to fix this problem. In 2.1, it had to be deliberately enabled in a module by including the directive from __future__ import nested_scopes at the top of a module, and the new scoping behaviour became the default only in Python 2.2. This was done to avoid breaking existing code whose behaviour would have changed as a result of the new scoping rules; Python 2.1 printed warnings about programs that were going to produce different results in Python 2.2 so that everyone had lots of time to fix their code. (See PEP 236 for a description of how incompatible changes are gradually introduced into Python.)

The first effect of static scoping was that the m=m default argument became unnecessary in the above example; the first version of the function now works as written. Under the new rules, when a given variable name is not assigned a value within a function (by an assignment, or the def , class , or import statements), references to the variable will be looked up in the local namespace of the enclosing scope. A more detailed explanation of the rules, and a dissection of the implementation, can be found in PEP 227: "Nested Scopes" . Scoping Rules

(Fixed in Python 2.1/2.2.)

This is another demonstration of the same problem. Recursive functions, as in following example, work fine when they're placed at the top-level of a module.:

def fact(n):
    if n == 1: return 1
    else: return n*fact(n-1)

However, if this definition is nested inside another function, it breaks as in the following example:

def g():
    def fact(n):
        if n == 1: return 1
        else: return n*fact(n-1)
    print fact(5)

When the nested version of fact() was called, it can't access its own name because the name fact was neither in the locals or in the module-level globals.:

[amk@mira amk]$ python2.1 /tmp/t.py
Traceback (innermost last):
  File "/tmp/t.py", line 8, in ?
    g()
  File "/tmp/t.py", line 6, in g
    print fact(5)
  File "/tmp/t.py", line 5, in fact
    else: return n*fact(n-1)
NameError: fact

This problem went away because of the static scoping introduced in Python 2.1 and described in the previous section.

[Nov 21, 2019] Python Functions

Nov 21, 2019 | www.w3schools.com

Passing a List as a Parameter

You can send any data types of parameter to a function (string, number, list, dictionary etc.), and it will be treated as the same data type inside the function.

E.g. if you send a List as a parameter, it will still be a List when it reaches the function:

Example def my_function(food):
for x in food:
print (x)

fruits = [ "apple" , "banana" , "cherry" ]

my_function(fruits)

Recommended Links

Google matched content

Softpanorama Recommended

Top articles

Sites



Etc

Society

Groupthink : Two Party System as Polyarchy : Corruption of Regulators : Bureaucracies : Understanding Micromanagers and Control Freaks : Toxic Managers :   Harvard Mafia : Diplomatic Communication : Surviving a Bad Performance Review : Insufficient Retirement Funds as Immanent Problem of Neoliberal Regime : PseudoScience : Who Rules America : Neoliberalism  : The Iron Law of Oligarchy : Libertarian Philosophy

Quotes

War and Peace : Skeptical Finance : John Kenneth Galbraith :Talleyrand : Oscar Wilde : Otto Von Bismarck : Keynes : George Carlin : Skeptics : Propaganda  : SE quotes : Language Design and Programming Quotes : Random IT-related quotesSomerset Maugham : Marcus Aurelius : Kurt Vonnegut : Eric Hoffer : Winston Churchill : Napoleon Bonaparte : Ambrose BierceBernard Shaw : Mark Twain Quotes

Bulletin:

Vol 25, No.12 (December, 2013) Rational Fools vs. Efficient Crooks The efficient markets hypothesis : Political Skeptic Bulletin, 2013 : Unemployment Bulletin, 2010 :  Vol 23, No.10 (October, 2011) An observation about corporate security departments : Slightly Skeptical Euromaydan Chronicles, June 2014 : Greenspan legacy bulletin, 2008 : Vol 25, No.10 (October, 2013) Cryptolocker Trojan (Win32/Crilock.A) : Vol 25, No.08 (August, 2013) Cloud providers as intelligence collection hubs : Financial Humor Bulletin, 2010 : Inequality Bulletin, 2009 : Financial Humor Bulletin, 2008 : Copyleft Problems Bulletin, 2004 : Financial Humor Bulletin, 2011 : Energy Bulletin, 2010 : Malware Protection Bulletin, 2010 : Vol 26, No.1 (January, 2013) Object-Oriented Cult : Political Skeptic Bulletin, 2011 : Vol 23, No.11 (November, 2011) Softpanorama classification of sysadmin horror stories : Vol 25, No.05 (May, 2013) Corporate bullshit as a communication method  : Vol 25, No.06 (June, 2013) A Note on the Relationship of Brooks Law and Conway Law

History:

Fifty glorious years (1950-2000): the triumph of the US computer engineering : Donald Knuth : TAoCP and its Influence of Computer Science : Richard Stallman : Linus Torvalds  : Larry Wall  : John K. Ousterhout : CTSS : Multix OS Unix History : Unix shell history : VI editor : History of pipes concept : Solaris : MS DOSProgramming Languages History : PL/1 : Simula 67 : C : History of GCC developmentScripting Languages : Perl history   : OS History : Mail : DNS : SSH : CPU Instruction Sets : SPARC systems 1987-2006 : Norton Commander : Norton Utilities : Norton Ghost : Frontpage history : Malware Defense History : GNU Screen : OSS early history

Classic books:

The Peter Principle : Parkinson Law : 1984 : The Mythical Man-MonthHow to Solve It by George Polya : The Art of Computer Programming : The Elements of Programming Style : The Unix Hater’s Handbook : The Jargon file : The True Believer : Programming Pearls : The Good Soldier Svejk : The Power Elite

Most popular humor pages:

Manifest of the Softpanorama IT Slacker Society : Ten Commandments of the IT Slackers Society : Computer Humor Collection : BSD Logo Story : The Cuckoo's Egg : IT Slang : C++ Humor : ARE YOU A BBS ADDICT? : The Perl Purity Test : Object oriented programmers of all nations : Financial Humor : Financial Humor Bulletin, 2008 : Financial Humor Bulletin, 2010 : The Most Comprehensive Collection of Editor-related Humor : Programming Language Humor : Goldman Sachs related humor : Greenspan humor : C Humor : Scripting Humor : Real Programmers Humor : Web Humor : GPL-related Humor : OFM Humor : Politically Incorrect Humor : IDS Humor : "Linux Sucks" Humor : Russian Musical Humor : Best Russian Programmer Humor : Microsoft plans to buy Catholic Church : Richard Stallman Related Humor : Admin Humor : Perl-related Humor : Linus Torvalds Related humor : PseudoScience Related Humor : Networking Humor : Shell Humor : Financial Humor Bulletin, 2011 : Financial Humor Bulletin, 2012 : Financial Humor Bulletin, 2013 : Java Humor : Software Engineering Humor : Sun Solaris Related Humor : Education Humor : IBM Humor : Assembler-related Humor : VIM Humor : Computer Viruses Humor : Bright tomorrow is rescheduled to a day after tomorrow : Classic Computer Humor

The Last but not Least Technology is dominated by two types of people: those who understand what they do not manage and those who manage what they do not understand ~Archibald Putt. Ph.D


Copyright © 1996-2021 by Softpanorama Society. www.softpanorama.org was initially created as a service to the (now defunct) UN Sustainable Development Networking Programme (SDNP) without any remuneration. This document is an industrial compilation designed and created exclusively for educational use and is distributed under the Softpanorama Content License. Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine.

FAIR USE NOTICE This site contains copyrighted material the use of which has not always been specifically authorized by the copyright owner. We are making such material available to advance understanding of computer science, IT technology, economic, scientific, and social issues. We believe this constitutes a 'fair use' of any such copyrighted material as provided by section 107 of the US Copyright Law according to which such material can be distributed without profit exclusively for research and educational purposes.

This is a Spartan WHYFF (We Help You For Free) site written by people for whom English is not a native language. Grammar and spelling errors should be expected. The site contain some broken links as it develops like a living tree...

You can use PayPal to to buy a cup of coffee for authors of this site

Disclaimer:

The statements, views and opinions presented on this web page are those of the author (or referenced source) and are not endorsed by, nor do they necessarily reflect, the opinions of the Softpanorama society. We do not warrant the correctness of the information provided or its fitness for any purpose. The site uses AdSense so you need to be aware of Google privacy policy. You you do not want to be tracked by Google please disable Javascript for this site. This site is perfectly usable without Javascript.

Last modified: August 10, 2020