<jupyter_start><jupyter_text>What are lambda functions in Python? In Python, an anonymous function is a function that is defined without a name.While normal functions are defined using the def keyword in Python, anonymous functions are defined using the lambda keyword.Hence, anonymous functions are also called lambda functions.Syntax of Lambda Function in python```lambda arguments: expression```<jupyter_code># use of lambda functions - Example 1
double = lambda x: x * 2

print(double(5))
# use of lambda functions - Example 2
add_square = lambda x,y: x**2+y**2

print(add_square(2,3))<jupyter_output>13<jupyter_text>Map functionBasic Syntax```map(function_object, iterable1, iterable2,...)```<jupyter_code># Example 1

def multiply2(x):
  return x * 2
    
map(multiply2, [1, 2, 3, 4])  # Output [2, 4, 6, 8]
# Example 2

map(lambda x : x*2, [1, 2, 3, 4]) #Output [2, 4, 6, 8]

# Example 3

dict_a = [{'name': 'python', 'points': 10}, {'name': 'java', 'points': 8}]
  
print(list(map(lambda x : x['name'], dict_a)))
  
print(list(map(lambda x : x['points']*10,  dict_a)))

print(list(map(lambda x : x['name'] == "python", dict_a)))

# Example 4

list_a = [1, 2, 3]
list_b = [10, 20, 30]
  
print(list(map(lambda x, y: x + y, list_a, list_b)))<jupyter_output>[11, 22, 33]<jupyter_text>Filter functionBasic Syntax```filter(function_object, iterable1, iterable2,...)```<jupyter_code># Example 1

a = [1, 2, 3, 4, 5, 6]
filter(lambda x : x % 2 == 0, a)
# Example 2

dict_a = [{'name': 'python', 'points': 10}, {'name': 'java', 'points': 8}, {'name': 'python', 'points': 10}]

filter(lambda x : x['name'] == 'python', dict_a)<jupyter_output><empty_output><jupyter_text>Comprehensions  Dictionary Comprehensions<jupyter_code># Example 1 

old_price = {'milk': 1.02, 'coffee': 2.5, 'bread': 2.5}

dollar_to_pound = 0.76
new_price = {item: value*dollar_to_pound for (item, value) in old_price.items()}
print(new_price)

# Example 2 - with if condition

original_dict = {'jack': 38, 'michael': 48, 'guido': 57, 'john': 33}

new_dict = {k: v for (k, v) in original_dict.items() if v % 2 != 0 if v < 40}
print(new_dict)
# Example 3 - with if else

original_dict = {'jack': 38, 'michael': 48, 'guido': 57, 'john': 33}

new_dict_1 = {k: ('old' if v > 40 else 'young')
    for (k, v) in original_dict.items()}
print(new_dict_1)
# Example 4 - nested dictionary comprehensions

dictionary = {
    k1: {k2: k1 * k2 for k2 in range(1, 6)} for k1 in range(2, 5)
}
print(dictionary)<jupyter_output>{2: {1: 2, 2: 4, 3: 6, 4: 8, 5: 10}, 3: {1: 3, 2: 6, 3: 9, 4: 12, 5: 15}, 4: {1: 4, 2: 8, 3: 12, 4: 16, 5: 20}}<jupyter_text>Set Comprehensions<jupyter_code># Example

names = [ 'Arnold', 'BILL', 'alice', 'arnold', 'MARY', 'J', 'BIll' ,'maRy']
res = {name.capitalize() for name in names if len(name) > 1}
res<jupyter_output><empty_output><jupyter_text>Global, Local and Nonlocal  Variable Scoping Global VariablesIn Python, a variable declared outside of the function or in global scope is known as a global variable. This means that a global variable can be accessed inside or outside of the function.<jupyter_code># example 1

x = "global"

def foo():
    print("x inside:", x)


foo()
print("x outside:", x)
# Example 2

x = 5

def foo():
    x = 5
    x = x * 2
    print(x)

foo()
# Example 3

x = 10
def foobar():
    global x
    print(x)
    x += 1
    print(x)

foobar()
print(x)<jupyter_output>10
11
11<jupyter_text>Rules of global KeywordThe basic rules for global keyword in Python are:- When we create a variable inside a function, it is local by default.- When we define a variable outside of a function, it is global by default. You don't have to use global keyword.- We use global keyword to read and write a global variable inside a function.- Use of global keyword outside a function has no effect.<jupyter_code># global keyword in nested functions

def foo():
    d = 20

    def bar():
        global d
        d +=1
        print(d)
    
    print("Before calling bar: ", d)
    print("Calling bar now")
    bar()
    print("After calling bar: ", d)

foo()

# print("x in main: ", d)<jupyter_output>Before calling bar:  20
Calling bar now<jupyter_text>Understanding nonlocal variableNonlocal variables are used in nested functions whose local scope is not defined. This means that the variable can be neither in the local nor the global scope.<jupyter_code>gv = "Some value" # global variable

def func():
    lv = "Some local value" # local variable
    def nested_func():
        global gv
        gv += " + Something else"
        print(gv)
        nonlocal lv
        lv += " + Something else"
        print(lv)
    nested_func()
    
func()
# Using nonlocal we can't change global scope variables

gv = "Some value" # global variable

def func():
    lv = "Some local value" # local variable
    def nested_func():
        nonlocal gv
        gv += " + Something else"
        print(gv)
        nonlocal lv
        lv += " + Something else"
        print(lv)
    nested_func()
    
func()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13805450566938532, 'fraction_numerical': 0.03600556992241894, 'mean_word_length': 3.8579710144927537, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 30, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '544343', 'license': 'Apache-2.0', 'n_tokens_mistral': 1912, 'n_tokens_neox': 1735, 'n_words': 630, 'path': 'notebooks/5_map_reduce_filter_lambda_scoping.ipynb', 'repo_name': 'inovizz/python-for-devops', 'size': '5027'}