<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Main</title>
    <description>The latest articles on Forem by Main (@mainpynerds).</description>
    <link>https://forem.com/mainpynerds</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1347100%2F64c722bc-aeb2-454d-8fc3-37162458d8e8.png</url>
      <title>Forem: Main</title>
      <link>https://forem.com/mainpynerds</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/mainpynerds"/>
    <language>en</language>
    <item>
      <title>dict.fromkeys() method in Python</title>
      <dc:creator>Main</dc:creator>
      <pubDate>Fri, 19 Apr 2024 23:17:49 +0000</pubDate>
      <link>https://forem.com/mainpynerds/dictfromkeys-method-in-python-4n3p</link>
      <guid>https://forem.com/mainpynerds/dictfromkeys-method-in-python-4n3p</guid>
      <description>&lt;p&gt;The&lt;code&gt;fromkeys()&lt;/code&gt; method of &lt;code&gt;dict&lt;/code&gt;type is used to  create a new dictionary with keys from a given iterable and values pre-filled with a specified default value.&lt;/p&gt;

&lt;p&gt;The syntax is as shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
dict.setdefault(iterable, value = None)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The items in the created dictionary has the elements from the &lt;code&gt;iterable&lt;/code&gt;as keys and the specified &lt;code&gt;value&lt;/code&gt;as the default value. If &lt;code&gt;value&lt;/code&gt;is not given, &lt;code&gt;None&lt;/code&gt;will be used.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
keys = [1, 2, 3, 4, 5]

d = dict.fromkeys(keys)
print(d)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the default value is given, the item's values will be populated with the value instead of &lt;code&gt;None&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
keys = ['one', 'two', 'three', 'four', 'five']

d = dict.fromkeys(keys, 0)
print(d)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example, we specified &lt;code&gt;0&lt;/code&gt; as the default value to the&lt;code&gt;fromkeys()&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;Note that the iterable argument can be any valid iterable not just lists. In the following example we use a range() for the iterable argument.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
d = dict.fromkeys(range(5))
print(d)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h3&gt;Related articles&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/dictionary-in-python/"&gt;Dictionary in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/python-dict-function/"&gt;Python dict() Function&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/dict-get-method-in-python/"&gt;dict.get() method in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/dict-update-method-in-python/"&gt;dict.update() method in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/items-keys-and-values-methods-in-python-dictionary/"&gt;items(), keys() and values() methods in Python dictionary&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/dict-pop-in-python/"&gt;dict.pop() in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/dict-clear-method-in-python/"&gt;dict.clear() method in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/dict-popitem-method-in-python/"&gt;dict.popitem() method in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/dict-setdefault-method-in-python/"&gt;dict.setdefault() method in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/dict-copy-method-in-python/"&gt;dict.copy() method in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>dict.setdefault() method in Python</title>
      <dc:creator>Main</dc:creator>
      <pubDate>Fri, 19 Apr 2024 23:11:09 +0000</pubDate>
      <link>https://forem.com/mainpynerds/dictsetdefault-method-in-python-3oml</link>
      <guid>https://forem.com/mainpynerds/dictsetdefault-method-in-python-3oml</guid>
      <description>&lt;p&gt;The &lt;code&gt;setdefault()&lt;/code&gt;method is used to retrieve a value from a dictionary given its key. If an item with the given key does not exist in the dictionary, it adds it and sets a given value for it.&lt;/p&gt;

&lt;p&gt;The syntax is as shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
d.setdefault(key, value = None)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;| &lt;code&gt;key&lt;/code&gt; | The key whose associated value is to be retrieved |&lt;br&gt;
| &lt;code&gt;value&lt;/code&gt; | The value to be set if the item with the given key does not exist. It defaults to None. |&lt;/p&gt;

&lt;p&gt;If an item of the given key exists, its value is returned. Otherwise, the key with the specified value is added to the dictionary and the value is returned.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
d = {
     'Tokyo': 'Japan',
     'Ottawa': 'Canada',
     'Kigali': 'Rwanda'
    }

value = d.setdefault('Kigali')
print(value)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example, we used the &lt;code&gt;setdefault()&lt;/code&gt;method with a key that exist in the dictionary, &lt;strong&gt;'Kigali'&lt;/strong&gt;. The value associated with the key is returned which is 'Rwanda'.&lt;/p&gt;

&lt;p&gt;Consider the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
d = {
     'Tokyo': 'Japan',
     'Ottawa': 'Canada',
     'Kigali': 'Rwanda'
    }

value = d.setdefault('Manilla')
print(value)

print(d)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example, the given key, &lt;strong&gt;'Manilla'&lt;/strong&gt; does not exist in the dictionary. The&lt;code&gt;setdefault()&lt;/code&gt; method adds an item with the key and sets a default value of &lt;code&gt;None&lt;/code&gt;to it because we did not specify another value.&lt;/p&gt;

&lt;p&gt;with a default value given&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
d = {
     'Tokyo': 'Japan',
     'Ottawa': 'Canada',
     'Kigali': 'Rwanda'
    }

value = d.setdefault('Manilla', 'Philippines')
print(value)

print(d)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h3&gt;Related articles&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/dictionary-in-python/"&gt;Dictionary in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/python-dict-function/"&gt;Python dict() Function&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/dict-get-method-in-python/"&gt;dict.get() method in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/dict-update-method-in-python/"&gt;dict.update() method in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/items-keys-and-values-methods-in-python-dictionary/"&gt;items(), keys() and values() methods in Python dictionary&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/dict-pop-in-python/"&gt;dict.pop() in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/dict-clear-method-in-python/"&gt;dict.clear() method in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/dict-fromkeys-method-in-python/"&gt;dict.fromkeys() method in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/dict-popitem-method-in-python/"&gt;dict.popitem() method in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/dict-copy-method-in-python/"&gt;dict.copy() method in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Implement Merge-Sort in python</title>
      <dc:creator>Main</dc:creator>
      <pubDate>Fri, 19 Apr 2024 22:38:22 +0000</pubDate>
      <link>https://forem.com/mainpynerds/implement-merge-sort-in-python-537b</link>
      <guid>https://forem.com/mainpynerds/implement-merge-sort-in-python-537b</guid>
      <description>&lt;p&gt;merge sort implementation&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
#merge sort

#the merge algorithm
def merge(L1, L2, L):
  i = 0
  j = 0
  while i+j &amp;lt; len(L):
    if j == len(L2) or (i &amp;lt; len(L1) and L1[i] &amp;lt; L2[j]):
       L[i+j] = L1[i]
       i += 1
    else:
       L[i+j] = L2[j]
       j += 1

#main function
def merge_sort(L):

  n = len(L)
  if n &amp;lt; 2:
     return # list is already sorted

  # divide
  mid = n // 2 #midpoint
  L1 = L[0:mid] # the first half
  L2 = L[mid:n] # the second half

  # conquer with recursion
  merge_sort(L1) # sort first sub-list
  merge_sort(L2) # sort second sub-list

  # merge result
  merge(L1, L2, L) 

#example
L = [7, 5, 1, 4, 2, 8, 0, 9, 3, 6]
print('Before: ', L)
merge_sort(L)
print('After: ', L)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The merge sort algorithm uses the &lt;strong&gt;divide and conquer&lt;/strong&gt;  technique to efficiently sort a list of elements.&lt;/p&gt;

&lt;p&gt;Divide and conquer involves breaking down a larger problem into smaller more manageable sub-problems, solving the sub-problems and then merging their solutions to solve the original problem.  In the case with merge-sort, the algorithm breaks down the list into smaller sub-lists, sorts those sub-lists recursively, and then merges the sorted sub-lists back together until the entire list is sorted&lt;/p&gt;

&lt;p&gt;Merge sort has  time complexity of &lt;code&gt;O(nlogn)&lt;/code&gt; in both average and worst case scenarios, this makes it one of the fastest sorting algorithms and consequently, one of the most sought after.&lt;/p&gt;

&lt;p&gt;Merge sort is stable, meaning that it preserves the relative order of equal elements in the original list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Algorithm Description
&lt;/h2&gt;

&lt;p&gt;Assuming we have a list &lt;strong&gt;L&lt;/strong&gt; , the basic steps followed by merge sort are as highlighted below:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;divide ** - If **L&lt;/strong&gt; has zero or one element, it is already sorted, immediately return &lt;strong&gt;L&lt;/strong&gt;. Otherwise, divide L's elements between two sub-lists, &lt;strong&gt;L1&lt;/strong&gt; and &lt;strong&gt;L2&lt;/strong&gt;.  Where, &lt;strong&gt;L1&lt;/strong&gt; contains first half of  the elements and &lt;strong&gt;L2&lt;/strong&gt; the rest..&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;conquer&lt;/strong&gt; - Recursively sort sub-lists &lt;strong&gt;L1&lt;/strong&gt; and &lt;strong&gt;L2&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;merge&lt;/strong&gt; - Combine the elements in a sorted state and put them back to&lt;code&gt;L&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;Consider if we want to sort the following list using merge sort.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vWNJ0Dvl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/dgc50iktu/image/upload/v1713216606/9b3e857f-527b-4712-a0b9-c7e1bb6b164c_dnv04j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vWNJ0Dvl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/dgc50iktu/image/upload/v1713216606/9b3e857f-527b-4712-a0b9-c7e1bb6b164c_dnv04j.png" alt="Unsorted list of values" width="416" height="74"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the first step of merge sort, the list will be recursively divided into individual sub-lists. This means that the list will be split into two sub-lists and then each of the sub-lists will be split into two more sub-lists, and so on until each sub-list contains only a single element. The following figure demonstrates the splitting phase:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2coNifPO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/dgc50iktu/image/upload/v1713216606/41d39c84-54c7-4c3b-adbe-1dd42e2ca83a_uyn9rb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2coNifPO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/dgc50iktu/image/upload/v1713216606/41d39c84-54c7-4c3b-adbe-1dd42e2ca83a_uyn9rb.png" alt="Splitting phase of merge sort" width="432" height="277"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After the divide step is over, we need to sort each sub-list and then recursively merge it with the other sorted sub-lists. This is known as the &lt;strong&gt;"conquer" step&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;At the beginning of the conquer step, each sub-lists is made up of a single element. Logically, a list with only one element is already sorted. Sublists with more than a single elements will have to be sorted before they are combined.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9w7hAzQS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/dgc50iktu/image/upload/v1713216605/8c4ea10f-2b79-404b-9654-0dedb84a7859_ptxj6b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9w7hAzQS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/dgc50iktu/image/upload/v1713216605/8c4ea10f-2b79-404b-9654-0dedb84a7859_ptxj6b.png" alt="conquer step in merge sort" width="432" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Merge sort implementation
&lt;/h2&gt;

&lt;p&gt;In this section, we will implement the merge sort algorithm using functions.&lt;/p&gt;

&lt;p&gt;For the sake of clarity, we will split the algorithm into two functions, &lt;code&gt;merge()&lt;/code&gt; and &lt;code&gt;merge_sort()&lt;/code&gt;. The &lt;code&gt;merge()&lt;/code&gt;function will be responsible for combining two already sorted sub-lists into a single sorted list. The &lt;code&gt;merge_sort()&lt;/code&gt; function is where the main logic of the algorithm will go.&lt;/p&gt;

&lt;p&gt;The merge() function&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
#L is the list while L1 and L2 are the sublists.

def merge(L1, L2, L):
  i = j = 0
  while i+j &amp;lt; len(L):
    if j == len(L2) or (i &amp;lt; len(L1) and L1[i] &amp;lt; L2[j]):
       L[i+j] = L1[i]
       i += 1

    else:
       L[i+j] = L2[j]
       j += 1

#example
L = [2, 7, 4, 0, 6, 5]
L1 = [2, 4, 7]
L2 = [0, 6, 5]

merge(L1, L2, L)
print(L)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;merge()&lt;/code&gt; function above takes in two sorted sub-lists(&lt;code&gt;L1&lt;/code&gt; and&lt;code&gt;L2&lt;/code&gt;) and puts their elements back to the original list(&lt;code&gt;L&lt;/code&gt;) in a sorted state. It does so by determining from which sub-list the next item should be taken before inserting the picked item back to list &lt;code&gt;L&lt;/code&gt;. For clarity, let us look at the function statement by statement:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;i = j = 0&lt;/code&gt; - This statement initializes two distinct variables, &lt;code&gt;i&lt;/code&gt; and &lt;code&gt;j&lt;/code&gt; each with a value of &lt;code&gt;0&lt;/code&gt;. The two variables&lt;code&gt;i&lt;/code&gt;, and &lt;code&gt;j&lt;/code&gt;represents the position of the current element in &lt;code&gt;L1&lt;/code&gt;and &lt;code&gt;L2&lt;/code&gt;, respectively.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;while i+j &amp;lt; len(L):&lt;/code&gt; -  Loop until the value of&lt;code&gt;i + j&lt;/code&gt; is greater than the length of the list. Note that at this point, the merge operation will be complete.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;if j == len(L2) or (i &amp;lt; len(L1) and L1[i] &amp;lt; L2[j]):
  L[i+j] = L1[i]
  i += 1&lt;/code&gt;
&lt;code&gt;else:
  L[i+j] = L2[j]
  j += 1&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;-The &lt;code&gt;j == len(L2)&lt;/code&gt; condition checks if there is elements to be picked in &lt;code&gt;L2&lt;/code&gt;, remember that&lt;code&gt;j&lt;/code&gt;represents the position of the current element in &lt;code&gt;L2&lt;/code&gt;, thus if it is equal to &lt;code&gt;len(L2)&lt;/code&gt;, it means that we have reached the end of &lt;code&gt;L2&lt;/code&gt;, so we pick the next element from &lt;code&gt;L1&lt;/code&gt; and insert it to&lt;code&gt;L&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
 -Due to the presence of &lt;code&gt;or&lt;/code&gt;, the second condition i.e &lt;code&gt;(i &amp;lt; len(L1) and L1[i] &amp;lt; L2[j])&lt;/code&gt;will only be tested if the first condition, i.e &lt;code&gt;(j == len(L2))&lt;/code&gt; fails,  it means that &lt;code&gt;L2&lt;/code&gt; still has element .  So we pick and insert into&lt;code&gt;L&lt;/code&gt; the smaller of the sub-lists' current element and then increment either &lt;code&gt;i&lt;/code&gt;or&lt;code&gt;j&lt;/code&gt;depending on whose sub-list's element was picked.&lt;br&gt;&lt;br&gt;
 -The &lt;code&gt;else&lt;/code&gt;statement also caters for when &lt;code&gt;L1&lt;/code&gt;has no more elements.&lt;/p&gt;

&lt;p&gt;After implementing the &lt;code&gt;merge(&lt;/code&gt;) function, the implementation of the &lt;code&gt;merge_sort()&lt;/code&gt;function become easier.&lt;/p&gt;

&lt;p&gt;implement&lt;code&gt;merge_sort()&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
#the implementation of merge() is omitted, refer to the previous snippet.

def merge_sort(L):

  n = len(L)
  if n &amp;lt; 2:
     return # list is already sorted

  # divide
  mid = n // 2 #midpoint
  L1 = L[0:mid] # the first half
  L2 = L[mid:n] # the second half

  # conquer
  merge_sort(L1) # recursively sort first sub-list
  merge_sort(L2) # recursively sort second sub-list

  # merge
  merge(L1, L2, L) 

#usage example
L = [99, 9, 0, 2, 1, 0, 1, 100, -2, 8, 7, 4, 3, 2]
merge_sort(L)
print(L)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;[-2, 0, 0, 1, 1, 2, 2, 3, 4, 7, 8, 9, 99, 100]&lt;/p&gt;

&lt;p&gt;The&lt;code&gt;merge_sort()&lt;/code&gt;function does not return any value because the sorting happens to the original list.&lt;/p&gt;

&lt;p&gt;The entire merge sort implementation is as shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
#merge sort implementation

def merge(L1, L2, L):
  i = 0
  j = 0
  while i+j &amp;lt; len(L):
    if j == len(L2) or (i &amp;lt; len(L1) and L1[i] &amp;lt; L2[j]):
       L[i+j] = L1[i]
       i += 1
    else:
       L[i+j] = L2[j]
       j += 1

def merge_sort(L):

  n = len(L)
  if n &amp;lt; 2:
     return # list is already sorted

  # divide
  mid = n // 2 #midpoint
  L1 = L[0:mid] # the first half
  L2 = L[mid:n] # the second half

  # conquer with recursion
  merge_sort(L1) # sort first sub-list
  merge_sort(L2) # sort second sub-list

  # merge result
  merge(L1, L2, L) 

#usage example
L = [99, 9, 0, 2, 1, 0, 1, 100, -2, 8, 7, 4, 3, 2]
merge_sort(L)
print(L)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Complexity analysis
&lt;/h2&gt;

&lt;p&gt;The time complexities of merge sort with a list of size &lt;code&gt;n&lt;/code&gt;, are as outlined below:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best case&lt;/strong&gt; - &lt;code&gt;O(nlogn&lt;/code&gt;) , this happens when the input list is already sorted.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Average case&lt;/strong&gt; -&lt;code&gt;O(nlogn)&lt;/code&gt;, when the input list is randomly sorted.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Worst case&lt;/strong&gt; - &lt;code&gt;O(nlogn)&lt;/code&gt;, when the input list is reverse sorted.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Space complexity
&lt;/h4&gt;

&lt;p&gt;Merge sort has a space complexity of&lt;code&gt;O(n)&lt;/code&gt; due to the space occupied by the sub-lists.&lt;/p&gt;


&lt;h3&gt;Related articles&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/pseudocodes-in-computer-programming/"&gt;Pseudocodes in Computer Programming&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/introduction-to-data-structures-algorithms/"&gt;Introduction to Data Structures &amp;amp; Algorithms&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/implement-stack-data-structure-in-python/"&gt;Implement Stack data structure in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/implement-queue-data-structure-in-python/"&gt;Implement Queue data structure in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/implement-fixed-length-stack-in-python/"&gt;Implement Fixed-length stack in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/implement-inorder-tree-traversal-python/"&gt;Implement Inorder Tree Traversal - Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/implement-bubble-sort-algorithm-in-python/"&gt;Implement bubble sort algorithm in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/implement-selection-sort-in-python/"&gt;Implement selection sort in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>csv module in Python</title>
      <dc:creator>Main</dc:creator>
      <pubDate>Fri, 19 Apr 2024 22:33:28 +0000</pubDate>
      <link>https://forem.com/mainpynerds/csv-module-in-python-kb5</link>
      <guid>https://forem.com/mainpynerds/csv-module-in-python-kb5</guid>
      <description>&lt;p&gt;The &lt;code&gt;csv&lt;/code&gt;module provide tools for working with and manipulating csv(comma separated values) files.&lt;br&gt;&lt;br&gt;
csv files are used to store tabular data in plain text formats. csv data consists of records and each record is made up of fields.  Normally, a line in a csv file represents a single record while fields in a record are separated by commas.&lt;/p&gt;

&lt;p&gt;The following is an example of csv data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
first_name,last_name,age,gender
John,Main,30,male
Jane,Doe,24,female
Morrison,Smith,22,male
Brian,Gates,32,male
Mary,Reagan,25,female
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Typically, files with a &lt;code&gt;.csv&lt;/code&gt;extension are normally associated with csv data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reading csv data
&lt;/h2&gt;

&lt;p&gt;To read data from a csv file, use the &lt;code&gt;reader()&lt;/code&gt;function. The function has the following basic syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
csv.reader(iterable)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;reader()&lt;/code&gt;function takes any iterable that yields a line during each iteration. This can be a file object, a list or any other iterable made of lines. It returns an iterator of lists, where each list represents a record in the csv data.&lt;/p&gt;

&lt;p&gt;Consider if the previous csv data exists in a file called &lt;code&gt;demo.csv&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import csv

with open('demo.csv') as file:
  reader = csv.reader(file)

  for row in reader:
     print(row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;['first_name', 'last_name', 'age', 'gender']&lt;br&gt;&lt;br&gt;
['John', 'Main', '30', 'male']&lt;br&gt;&lt;br&gt;
['Jane', 'Doe', '24', 'female']&lt;br&gt;&lt;br&gt;
['Morrison', 'Smith', '22', 'male']&lt;br&gt;&lt;br&gt;
['Brian', 'Gates', '32', 'male']&lt;br&gt;&lt;br&gt;
['Mary', 'Reagan', '25', 'female']&lt;/p&gt;

&lt;p&gt;In the above example, we used data stored in a file object but as earlier mentioned, you can literally use any iterable. In the following example, we use a list instead of a file object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import csv

data = """first_name,last_name,age,gender
John,Main,30,male
Jane,Doe,24,female
Morrison,Smith,22,male
Brian,Gates,32,male
Mary,Reagan,25,female"""

reader = csv.reader(data.splitlines())
for row in reader:
  print(row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;['first_name', 'last_name', 'age', 'gender']&lt;br&gt;&lt;br&gt;
['John', 'Main', '30', 'male']&lt;br&gt;&lt;br&gt;
['Jane', 'Doe', '24', 'female']&lt;br&gt;&lt;br&gt;
['Morrison', 'Smith', '22', 'male']&lt;br&gt;&lt;br&gt;
['Brian', 'Gates', '32', 'male']&lt;br&gt;&lt;br&gt;
['Mary', 'Reagan', '25', 'female'] &lt;/p&gt;
&lt;h2&gt;
  
  
  Writing csv data
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;writer()&lt;/code&gt; function creates an object for writing csv data. It has the following basic syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
csv.writer(fileobj)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where the &lt;code&gt;fileobj&lt;/code&gt;is the opened file where the csv data will be written to.&lt;/p&gt;

&lt;p&gt;After creating the writer object, we can then use&lt;code&gt;writerow()&lt;/code&gt; method to write a single record into the file or &lt;code&gt;writerows()&lt;/code&gt; to write multiple rows at once.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import csv

with open('demo.csv', 'a') as file:
  writer = csv.writer(file)

  writer.writerow(('Ruth', 'Miller', 24, 'female'))
  writer.writerow(('Brandy', 'Jones', 22, 'male'))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that in the above example, we opened the &lt;code&gt;demo.csv&lt;/code&gt; file with the &lt;code&gt;"a"&lt;/code&gt; mode. This ensures that the new rows are appended to the file, if we had used the &lt;code&gt;"w"&lt;/code&gt; mode instead, the existing rows would have been overwritten.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import csv

with open('demo.csv') as file:
  print(file.read())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;first_name,last_name,age,gender&lt;br&gt;&lt;br&gt;
John,Main,30,male&lt;br&gt;&lt;br&gt;
Jane,Doe,24,female&lt;br&gt;&lt;br&gt;
Morrison,Smith,22,male&lt;br&gt;&lt;br&gt;
Brian,Gates,32,male&lt;br&gt;&lt;br&gt;
Mary,Reagan,25,female&lt;br&gt;&lt;br&gt;
Ruth,Miller,24,female&lt;/p&gt;

&lt;p&gt;Brandy,Jones,22,male&lt;/p&gt;

&lt;p&gt;As you can see above, the new records have been added successfully.&lt;/p&gt;

&lt;p&gt;To add multiple rows at once,  use the &lt;code&gt;writer.writerows()&lt;/code&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import csv

rows = [
   ('Stephen', 'King', 32, 'male'),
   ('Molly', 'Jones', 22, 'female')
  ]

with open('demo.csv', 'a') as file:
  writer = csv.writer(file)
  writer.writerows(rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Quoting behavior
&lt;/h3&gt;

&lt;p&gt;In cases where you want records of certain types to be stored in quotes, you can specify the &lt;code&gt;quoting&lt;/code&gt;flag when creating the &lt;code&gt;writer&lt;/code&gt; object. For example, if you want string items to be in quotes but numeric values not to be, you can specify the quoting parameter as &lt;code&gt;csv.QUOTE_NONNUMERIC&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import csv

rows = [
   ('Stephen', 'King', 32, 'male'),
   ('Molly', 'Jones', 22, 'female')
  ]

with open('demo.csv', 'w') as file:
  writer = csv.writer(file, quoting = csv.QUOTE_NONNUMERIC)
  writer.writerows(rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you open the&lt;code&gt;demo.csv&lt;/code&gt;file, you will see that in the written records , string fields are quoted.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import csv

with open('demo.csv') as file:
  print(file.read())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;"Stephen","King",32,"male"&lt;/p&gt;

&lt;p&gt;"Molly","Jones",22,"female"&lt;/p&gt;

&lt;p&gt;All the quoting options are as shown in the following table:&lt;/p&gt;

&lt;p&gt;| &lt;code&gt;QUOTE_ALL&lt;/code&gt; | Quote any field regardless of type |&lt;br&gt;
| &lt;code&gt;QUOTE_NONE&lt;/code&gt; | Don't quote any field. |&lt;br&gt;
| &lt;code&gt;QUOTE_MINIMAL&lt;/code&gt; | Quote only fields containing some special characters. This is the default quoting behavior. |&lt;br&gt;
| &lt;code&gt;QUOTE_NONNUMERIC&lt;/code&gt; | Quote all fields except those with numeric values like integers and floats. |&lt;/p&gt;
&lt;h2&gt;
  
  
  csv dialects
&lt;/h2&gt;

&lt;p&gt;Separating csv fields with a comma is just the popular convention, there is  really no well defined standard on csv format.  For example, you could as well separate the fields with spaces instead of commas.  This means that any csv parser needs to be very flexible when dealing with csv delimiters.&lt;/p&gt;

&lt;p&gt;Dialects allow us to specify to the parser the delimiter and other important parameters that will be used when parsing the csv files. The &lt;code&gt;csv.list_dialects()&lt;/code&gt; function returns a list of the registered dialects.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import csv

print(csv.list_dialects())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;['excel', 'excel-tab', 'unix']&lt;/p&gt;

&lt;p&gt;The default dialect is &lt;code&gt;excel&lt;/code&gt;, in which the fields are delimited with commas.&lt;/p&gt;

&lt;p&gt;If for example, you have csv data in which the fields are delimited by a pipe character&lt;code&gt;"|"&lt;/code&gt; or any other character instead of a comma, as shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
first_name|last_name|age|gender
John|Main|30|male
Jane|Doe|24|female
Morrison|Smith|22|male
Brian|Gates|32|male
Mary|Reagan|25|female
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can register a new dialect using the&lt;code&gt;csv.register_dialect()&lt;/code&gt;. You can then use the registered dialect with &lt;code&gt;reader&lt;/code&gt;and &lt;code&gt;writer&lt;/code&gt;objects.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import csv

data = """first_name|last_name|age|gender
John|Main|30|male
Jane|Doe|24|female
Morrison|Smith|22|male
Brian|Gates|32|male
Mary|Reagan|25|female"""

csv.register_dialect('pipe', delimiter = '|')
print("Dialects: ", csv.list_dialects())

reader = csv.reader(data.splitlines(), dialect = 'pipe') #use the dialect

for row in reader:
  print(row)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apart from &lt;code&gt;delimiter&lt;/code&gt;, you can specify other dialect parameters depending on the nature of your csv  data. The supported parameters are shown in the following tables:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;parameter&lt;/th&gt;
&lt;th&gt;default value&lt;/th&gt;
&lt;th&gt;description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;delimiter&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;,&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Field separator.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;quotechar&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The character to enclose fields where quoting is allowed.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lineterminator&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;\r \n&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The string/character used to terminate a line&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;doublequote&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;True&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Whether quotchar parameters are doubled.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;escapechar&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;None&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Character used to indicate an escape sequence&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;skipintialspace&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;False&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Ignore whitespace after the delimiter&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Automatic dialect detection
&lt;/h3&gt;

&lt;p&gt;In cases where the csv format is not well known, we can use the &lt;code&gt;csv.Sniffer&lt;/code&gt;class, which automatically constructs a dialect object given a sample of csv data.&lt;/p&gt;

&lt;p&gt;Consider if we have the following csv data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
​first_name&amp;amp;last_name&amp;amp;age&amp;amp;gender
John&amp;amp;Main&amp;amp;30&amp;amp;male
Jane&amp;amp;Doe&amp;amp;24&amp;amp;female
Morrison&amp;amp;Smith&amp;amp;22&amp;amp;male
Brian&amp;amp;Gates&amp;amp;32&amp;amp;male
Mary&amp;amp;Reagan&amp;amp;25&amp;amp;female
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example, we used the &lt;code&gt;"&amp;amp;"&lt;/code&gt;character as the delimiter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import csv

data="""first_name&amp;amp;last_name&amp;amp;age&amp;amp;gender
John&amp;amp;Main&amp;amp;30&amp;amp;male
Jane&amp;amp;Doe&amp;amp;24&amp;amp;female
Morrison&amp;amp;Smith&amp;amp;22&amp;amp;male
Brian&amp;amp;Gates&amp;amp;32&amp;amp;male
Mary&amp;amp;Reagan&amp;amp;25&amp;amp;female"""

sniffer=csv.Sniffer()
dialect=sniffer.sniff(sample=data)

print("delimiter: ", dialect.delimiter)

reader = csv.reader(data.splitlines(), dialect = dialect)
for row in reader:
  print(row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, the sniffer correctly detected that &lt;code&gt;"&amp;amp;"&lt;/code&gt; is used as the delimiter character.  However, you should keep in mind that the sniffer is not always correct, it can only be said to be making educated guesses.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using named fields
&lt;/h2&gt;

&lt;p&gt;You can use&lt;code&gt;csv.DictReader&lt;/code&gt; and &lt;code&gt;csv.DictWriter&lt;/code&gt;classes to use named fields when reading or writing csv data.&lt;/p&gt;

&lt;p&gt;The two classes allows you to specify in advance a list of field names to alias the fields in the csv data.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;csv.DictReader&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;DictReader&lt;/code&gt;class allows you to read rows with the fields having an alias name.&lt;/p&gt;

&lt;p&gt;Consider the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import csv

data = """first_name,last_name,age,gender
John,Main,30,male
Jane,Doe,24,female
Morrison,Smith,22,male
Brian,Gates,32,male
Mary,Reagan,25,female"""

fields = 'fname', 'lname', 'age', 'gender'

reader = csv.DictReader(data.splitlines(), fieldnames = fields)
for row in reader:
  print(row['fname'], row['lname'])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Iterating through the &lt;code&gt;DictReader&lt;/code&gt;object will yield a list of dictionaries, where each dictionary represents a row in the csv data.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;csv.DictWriter&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;DictWriter&lt;/code&gt; objects writes data into a csv file with argument given as dictionaries. Consider the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import csv

fields = 'fname', 'lname', 'age', 'gender'
data_to_wite = [
    {'fname':'Stephen', 'lname':'King', 'age':32, 'gender':'male'},
    {'age':22, 'lname':'Jones', 'fname':'Molly', 'gender':'female'},
]

with open('pynerds.txt', 'w') as file:
  writer = csv.DictWriter(file, fieldnames = fields)
  writer.writerows(data_to_wite)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As shown above, when using named fields, the order is not important as long as the field names are correct.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import csv

with open('demo.csv') as file:
  print(file.read())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Stephen,King,32,male&lt;/p&gt;

&lt;p&gt;Molly,Jones,22,female&lt;/p&gt;


&lt;h3&gt;Related articles&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/working-with-text-files-in-python/"&gt;Working with Text files in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/working-with-csv-files-in-python/"&gt;Working with CSV files in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/working-with-json-files-in-python/"&gt;Working with JSON files in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/working-with-pdf-files-in-python-pypdf2-library/"&gt;Working with PDF files in Python-PyPDF2 Library.&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/working-with-zip-files-in-python-read-create-write-extract/"&gt;Working with zip files in Python-(read, create, write, extract)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/parsing-xml-in-python-with-etree-elementtree/"&gt;Parsing xml in Python with etree.ElementTree&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>items(), keys() and values() methods in Python dictionary</title>
      <dc:creator>Main</dc:creator>
      <pubDate>Mon, 15 Apr 2024 01:34:19 +0000</pubDate>
      <link>https://forem.com/mainpynerds/items-keys-and-values-methods-in-python-dictionary-2n2k</link>
      <guid>https://forem.com/mainpynerds/items-keys-and-values-methods-in-python-dictionary-2n2k</guid>
      <description>&lt;p&gt;An element in a dictionary is also called an  &lt;strong&gt;item&lt;/strong&gt;. Each item is made up of a &lt;strong&gt;key&lt;/strong&gt; and a &lt;strong&gt;value&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1706726328%2F0b233f60-a941-4fd7-8885-60c39de9d3b3_syxepq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1706726328%2F0b233f60-a941-4fd7-8885-60c39de9d3b3_syxepq.png" alt="Dictionary constituents"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The three dictionary methods; &lt;code&gt;items()&lt;/code&gt;, &lt;code&gt;keys()&lt;/code&gt; and &lt;code&gt;values()&lt;/code&gt;retrieves all items, keys and values respectively.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;items()&lt;/code&gt; - Returns an iterable of all key-value pairs(items) present in the dictionary.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;keys()&lt;/code&gt; - Returns an iterable with all the keys in the dictionary.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;values()&lt;/code&gt;- Returns an iterable with all the values in the dictionary.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  items() - Get all items present in a dictionary
&lt;/h2&gt;

&lt;p&gt;To get an iterable containing all the items present in a dictionary, use the&lt;code&gt;items()&lt;/code&gt;method. The syntax is as shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
d.items()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The method does not take any argument.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
d = {
      'Spain': 'Madrid',
      'Italy': 'Rome',
      'France': 'paris'
    }
#get the items
all_items = d.items()

print(all_items)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;items()&lt;/code&gt;method is useful when it comes to iterating over the dictionary items. Remember that iterating over a dictionary only yields its keys, so using the &lt;code&gt;items()&lt;/code&gt;method allows you to access both the key and its corresponding value in one iteration.&lt;/p&gt;

&lt;p&gt;iterating through a dictionary&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
d = {
      'Spain': 'Madrid',
      'Italy': 'Rome',
      'France': 'paris'
    }

for i in d:
   print(i)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example, we used the for loop to iterate over a dictionary. As you can see, only the keys are returned. Now consider the same example with the &lt;code&gt;items()&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;iterating over items()&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
d = {
      'Spain': 'Madrid',
      'Italy': 'Rome',
      'France': 'paris'
    }

for i in d.items():
   print(i)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, iterating through the &lt;code&gt;items()&lt;/code&gt; object returns tuples in the form &lt;code&gt;(key, value)&lt;/code&gt; for each dictionary item.&lt;/p&gt;

&lt;h2&gt;
  
  
  keys() - get all keys of a dictionary
&lt;/h2&gt;

&lt;p&gt;The&lt;code&gt;keys()&lt;/code&gt;method returns an object containing all the keys present in a dictionary.&lt;/p&gt;

&lt;p&gt;it has the following syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
d.keys()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The method does not take any arguments.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
d = {
      'Spain': 'Madrid',
      'Italy': 'Rome',
      'France': 'paris'
    }
#get the keys
all_keys = d.keys()

print(all_keys)
print(type(all_keys))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can iterate through the returned object to get individual keys at each iteration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
d = {
      'Spain': 'Madrid',
      'Italy': 'Rome',
      'France': 'paris'
    }
#iterate through the keys
for k in d.keys():
   print(k)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  values() - get all values in the dictionary
&lt;/h2&gt;

&lt;p&gt;Finally, the &lt;code&gt;values()&lt;/code&gt; method returns an object containing all the keys in the dictionary. It has the following syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
d.values()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The method does not take arguments.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
d = {
      'Spain': 'Madrid',
      'Italy': 'Rome',
      'France': 'paris'
    }
#get the keys
all_values = d.values()

print(all_values)
print(type(all_values))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;iterate through the values&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
d = {
      'Spain': 'Madrid',
      'Italy': 'Rome',
      'France': 'paris'
    }
#iterate through the keys
for v in d.values():
   print(v)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;items()&lt;/code&gt;to get an iterable of two length tuples, where each tuple contains a key and a value of a dictionary item.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;keys()&lt;/code&gt; to get an iterable of all the keys present in a dictionary.&lt;/li&gt;
&lt;li&gt;use &lt;code&gt;values()&lt;/code&gt; to get an iterable of all the values present in a dictionary.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Related articles&lt;/h3&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/dictionary-in-python/" rel="noopener noreferrer"&gt;Dictionary in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/python-dict-function/" rel="noopener noreferrer"&gt;Python dict() Function&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/dict-get-method-in-python/" rel="noopener noreferrer"&gt;dict.get() method in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/dict-update-method-in-python/" rel="noopener noreferrer"&gt;dict.update() method in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/dict-pop-in-python/" rel="noopener noreferrer"&gt;dict.pop() in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/dict-clear-method-in-python/" rel="noopener noreferrer"&gt;dict.clear() method in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/dict-fromkeys-method-in-python/" rel="noopener noreferrer"&gt;dict.fromkeys() method in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/dict-popitem-method-in-python/" rel="noopener noreferrer"&gt;dict.popitem() method in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/dict-setdefault-method-in-python/" rel="noopener noreferrer"&gt;dict.setdefault() method in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/dict-copy-method-in-python/" rel="noopener noreferrer"&gt;dict.copy() method in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Linked list vs Array</title>
      <dc:creator>Main</dc:creator>
      <pubDate>Mon, 15 Apr 2024 01:27:52 +0000</pubDate>
      <link>https://forem.com/mainpynerds/linked-list-vs-array-2jd7</link>
      <guid>https://forem.com/mainpynerds/linked-list-vs-array-2jd7</guid>
      <description>&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/singly-linked-list-in-python/" rel="noopener noreferrer"&gt;Linked lists&lt;/a&gt; and arrays are two commonly used data structures. Each has its own advantages and disadvantages, and is suitable for  specific scenarios than others. In this article we will compare the two data structures on various basis.&lt;/p&gt;

&lt;h2&gt;
  
  
  Definitions
&lt;/h2&gt;

&lt;p&gt;An array is a data structure that stores a fixed-size collection of elements of the same type. The elements are stored contiguously in memory and each element can be accessed using an index. Lists in Python are implemented through arrays.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
arr = ['Java', 'Python', 'Ruby', 'C++'] # an array

#get an element at specific index
print(arr[2]) # the element at the third position

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the other hand, a linked list is a linear data structure in which elements are connected through references. Each element, also known as a &lt;strong&gt;node&lt;/strong&gt; , contains a data field and a reference to the next node in the list.  Basically, a node in a linked list will look as shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
class Node:
    def __init__ (self, element, nxt):
        self.data = element #Users element
        self.next = nxt #The next node in the list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The  &lt;code&gt;data&lt;/code&gt; instance attribute keeps the value of the element stored by the node,  while the &lt;code&gt;next&lt;/code&gt;attribute stores a reference to the next node in the list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Insertion and Deletion
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Arrays
&lt;/h3&gt;

&lt;p&gt;Insertion and deletion in an array can be expensive, especially if the size is large and the element is inserted or deleted from the beginning or middle of the array.&lt;/p&gt;

&lt;p&gt;When you insert or delete an element at an arbitrary position in an array, each elements after that position shifts.&lt;/p&gt;

&lt;p&gt;In case with insertion, the elements shifts  to the right, creating a gap for the new element to be inserted. The following figure illustrates this better.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1708311493%2Fc48feb68-f7a9-4be0-b4d1-8aaaa5c6bbe1_pskxry.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1708311493%2Fc48feb68-f7a9-4be0-b4d1-8aaaa5c6bbe1_pskxry.png" alt="shift elements in an array to create space."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1708311469%2F5e41c387-65a5-4752-8726-c0c9c6d4470e_u95pdd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1708311469%2F5e41c387-65a5-4752-8726-c0c9c6d4470e_u95pdd.png" alt="After element in an array shifts"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1708311462%2Fb596c2e8-9402-4075-a828-b8c7960becd7_lj5cib.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1708311462%2Fb596c2e8-9402-4075-a828-b8c7960becd7_lj5cib.png" alt="After inserting the element."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With deletion, the elements shifts to the left to occupy the space that has been left by the removed element.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1708312496%2F90d9a7b5-e916-468b-b6f5-4c8452fb0e8c_vzb5ek.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1708312496%2F90d9a7b5-e916-468b-b6f5-4c8452fb0e8c_vzb5ek.png" alt="the element to be removed from the array"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1708312503%2Fca7fc7ba-03dc-4077-a183-2820f5aa936b_s0qocn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1708312503%2Fca7fc7ba-03dc-4077-a183-2820f5aa936b_s0qocn.png" alt="A hole created"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1708312511%2F4e41c593-ddf1-4da3-b494-4ab4214e7bb1_gohfhi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1708312511%2F4e41c593-ddf1-4da3-b494-4ab4214e7bb1_gohfhi.png" alt="Elements shifts"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1708312521%2Fca8ff32a-d02f-4547-907d-c63d978ca075_sj91hb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1708312521%2Fca8ff32a-d02f-4547-907d-c63d978ca075_sj91hb.png" alt="array after elements have shifted"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Insertion and deletion in arrays have a worst case time complexity of &lt;code&gt;O(n)&lt;/code&gt;, as all the elements after the insertion or deletion shifts.This can be costly for large arrays with a lot of elements.&lt;/p&gt;

&lt;p&gt;The only exception is when insertion or deletion happens at the end of the array, as there is no need to shift any elements. Insertion and deletion at the last position has a time complexity of &lt;code&gt;O(1)&lt;/code&gt;. This makes the end of an array the best place to insert or delete elements if possible&lt;/p&gt;

&lt;h4&gt;
  
  
  Linked list
&lt;/h4&gt;

&lt;p&gt;Insertion and deletion in a linked list is easier and much more efficient compared to in array. In a linked list, both insertion and deletion have a constant time complexity, &lt;code&gt;O(1)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With insertion, the new element can be inserted at any position by just updating the relevant nodes to reference the new node. While with deletion, an element can simply be dereferenced and removed from the list without affecting the references of other nodes. This is because each node only has a reference to the next node, so removing one node does not affect the references of other nodes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Accessing elements
&lt;/h2&gt;

&lt;p&gt;Accessing elements in an array is much more efficient compared to in a linked list. The elements in arrays are stored in contagious memory locations, we can, therefore, directly access an element using its index. This ensures a constant time complexity(&lt;code&gt;O(1)&lt;/code&gt;) regardless of the size of the array or the location of the element to be accessed.&lt;/p&gt;

&lt;p&gt;On the other hand, elements in linked list are scattered throughout the memory, thus we have to traverse the entire list to access a specific element.  Since the elements are not stored contiguously we cannot use index to access an element, we have to traverse the list starting from the head node until we reach the desired element Thus, accessing elements has a worst case time complexity of &lt;code&gt;O(n)&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Memory allocation and efficiency
&lt;/h2&gt;

&lt;p&gt;Arrays are more memory-efficient as they only require memory for the individual elements, and not for any additional references. However, they also have a fixed size that cannot be changed, this makes them less flexible and not very suitable for representing  dynamic data.&lt;/p&gt;

&lt;p&gt;A linked list requires extra memory to store the references, which can be disadvantageous if the list contains a large number of elements. On the better side, memory allocation for a linked list is dynamic, meaning new nodes can be allocated as and when needed. This makes linked lists flexible for adding or removing elements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Array&lt;/th&gt;
&lt;th&gt;Linked list&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A collection of homogeneous items in which an item can be accessed using its index&lt;/td&gt;
&lt;td&gt;A sequence of nodes where each node references the next node in the list.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Have a fixed size that is defined at declaration.&lt;/td&gt;
&lt;td&gt;Are of dynamic size.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Faster access to elements as each element can be accessed with its index at a time complexity of &lt;code&gt;O(1)&lt;/code&gt;.&lt;/td&gt;
&lt;td&gt;Accessing elements is inefficient and has a worst time complexity of &lt;code&gt;O(n)&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Insertion and deletion operations become more inefficient the closer you move to the beginning of the array. Both has a worst time complexity of &lt;code&gt;O(n)&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Very efficient insertion and deletion operations. Both operations have a time complexity of &lt;code&gt;O(1)&lt;/code&gt; at any position.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Relatively less memory footprint as only the elements are stored.&lt;/td&gt;
&lt;td&gt;More memory footprint, as references to other nodes have to be stored in addition to the actual element.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h3&gt;Related articles&lt;/h3&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/list-data-type-in-python/" rel="noopener noreferrer"&gt;List Data Type in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/complexity-functions-in-algorithm-analysis/" rel="noopener noreferrer"&gt;Complexity Functions in algorithm analysis&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/implement-stack-data-structure-in-python/" rel="noopener noreferrer"&gt;Implement Stack data structure in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/implement-queue-data-structure-in-python/" rel="noopener noreferrer"&gt;Implement Queue data structure in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/implement-fixed-length-stack-in-python/" rel="noopener noreferrer"&gt;Implement Fixed-length stack in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/double-ended-queue-in-python/" rel="noopener noreferrer"&gt;Double-ended Queue in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/doubly-linked-list-in-python/" rel="noopener noreferrer"&gt;Doubly-Linked List in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/binary-trees-in-python/" rel="noopener noreferrer"&gt;Binary Trees in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/tree-traversal-algorithms/" rel="noopener noreferrer"&gt;Tree traversal algorithms&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/implement-selection-sort-in-python/" rel="noopener noreferrer"&gt;Implement selection sort in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Insertion sort in Python</title>
      <dc:creator>Main</dc:creator>
      <pubDate>Mon, 15 Apr 2024 01:16:24 +0000</pubDate>
      <link>https://forem.com/mainpynerds/implement-insertion-sort-in-python-4ef7</link>
      <guid>https://forem.com/mainpynerds/implement-insertion-sort-in-python-4ef7</guid>
      <description>&lt;p&gt;Insertion sort is a simple yet relatively efficient comparison-based sorting algorithm.&lt;/p&gt;

&lt;p&gt;Compared to other basic sorting algorithm such as &lt;a href="https://www.pynerds.com/data-structures/implement-bubble-sort-algorithm-in-python/" rel="noopener noreferrer"&gt;bubble sort&lt;/a&gt;and &lt;a href="https://www.pynerds.com/data-structures/implement-selection-sort-in-python/" rel="noopener noreferrer"&gt;selection sort&lt;/a&gt;,  insertion sort  performs relatively well especially  on small-to-medium and &lt;strong&gt;mostly sorted&lt;/strong&gt; lists. It also has a stable sorting behavior, meaning that elements with equal values will maintain their original relative order after sorting.&lt;/p&gt;

&lt;p&gt;Insertion sort works in-place, in that it re-arranges the elements of the original list instead of creating a new list. This makes it efficient in terms of memory usage.&lt;/p&gt;

&lt;p&gt;Compared to other advanced sorting algorithm such as &lt;code&gt;quicksort&lt;/code&gt;and &lt;code&gt;mergesort&lt;/code&gt;, insertion sort is relatively easy to understand and implement. However it has an average and  worst-time complexities of&lt;code&gt;O(n2)&lt;/code&gt;, this means that it can be inefficient when sorting large dataset. It works well when the input list is small in size and or it is nearly sorted.&lt;/p&gt;

&lt;h2&gt;
  
  
  Algorithm Description
&lt;/h2&gt;

&lt;p&gt;In insertion sort, the input array/list is divided into two segments, the &lt;strong&gt;sorted segment&lt;/strong&gt;  on the left and the *&lt;em&gt;unsorted segment *&lt;/em&gt; on the right. Initially, the sorted segment is made up of only the first element of the list, while the unsorted segment is made up of the rest of the list elements.&lt;/p&gt;

&lt;p&gt;The algorithm iterates through the unsorted segment and takes one element at a time, comparing it with the elements in the sorted segment. It finds the correct position for the element in the sorted segment and &lt;strong&gt;inserts&lt;/strong&gt; it there, shifting the other elements if necessary. The process continues until all elements in the unsorted segment are inserted into their correct positions in the sorted segment.&lt;/p&gt;

&lt;p&gt;The following is the higher-level description of the steps in the insertion sort algorithm:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The first element is already sorted.&lt;/li&gt;
&lt;li&gt;Pick the  next element.&lt;/li&gt;
&lt;li&gt;Compare it with the the elements in the sorted segment.&lt;/li&gt;
&lt;li&gt;Insert it before all larger elements.&lt;/li&gt;
&lt;li&gt;Repeat &lt;strong&gt;steps 2-4&lt;/strong&gt; with the rest of the unsorted elements until the entire list is sorted. &lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Insertion sort Example
&lt;/h3&gt;

&lt;p&gt;In this part we will demonstrate the steps insertion sort algorithm would follow to sort the following  list.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1713132612%2F9d7929d6-c262-4a60-9416-6d750bba8a64_-_Copy_tdb8um.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1713132612%2F9d7929d6-c262-4a60-9416-6d750bba8a64_-_Copy_tdb8um.png" alt="Unsorted list"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the first step the sorted segment is only made up of the first element of the list. Logically, a list with only one item is already sorted.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1713132612%2F45a6f035-9c7e-4c92-bd37-4b00dbcc7d1f_-_Copy_wvma02.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1713132612%2F45a6f035-9c7e-4c92-bd37-4b00dbcc7d1f_-_Copy_wvma02.png" alt="the sorted segment is made up of only the first item in the list."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will use color green to indicate the elements in the sorted segment and red for element in the unsorted segment.&lt;/p&gt;

&lt;p&gt;We start by picking an unsorted element and placing it at its position in the sorted segment. The first unsorted element is &lt;code&gt;4&lt;/code&gt;, so we pick it and insert it at its place in the sorted segment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1713132611%2F6d3f658b-d10d-4c16-8cdb-3e6a8f34103d_eicy7q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1713132611%2F6d3f658b-d10d-4c16-8cdb-3e6a8f34103d_eicy7q.png" alt="Pick the first element in the unsorted segment and place it in the sorted segment."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the above  case, &lt;code&gt;4&lt;/code&gt; is smaller than&lt;code&gt;7&lt;/code&gt; so the two are swapped. We now move on to the next unsorted element which is &lt;code&gt;8&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1713132612%2FInsertion_3_-_Edited_-_Copy_ld5tf6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1713132612%2FInsertion_3_-_Edited_-_Copy_ld5tf6.png" alt="8 is already sorted."&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;In the above case, we found that &lt;code&gt;8&lt;/code&gt; is already sorted so no need for performing any action.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1713132611%2Fdf6d55ca-5be0-4cd8-bf04-00dc3aa10934_tcecge.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1713132611%2Fdf6d55ca-5be0-4cd8-bf04-00dc3aa10934_tcecge.png" alt="Insert 5 at its place"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;After placing &lt;code&gt;5&lt;/code&gt; at its place, the unsorted segment is now only made up of a single element, &lt;code&gt;6&lt;/code&gt;. let us put it in its place.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1713132611%2F1799806d-f397-4e80-bff2-42477690b576_d3zpfs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1713132611%2F1799806d-f397-4e80-bff2-42477690b576_d3zpfs.png" alt="The final step of insertion sort"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After performing the above step, we are done and the list is now sorted.&lt;/p&gt;

&lt;h2&gt;
  
  
  Insertion sort implementation.
&lt;/h2&gt;

&lt;p&gt;We can implement insertion sort through nested loops. the first loop picks the current unsorted element and the inner loop inserts it at its place in the sorted segment. The most suitable approach of implementing this is by use of an outer &lt;a href="https://www.pynerds.com/python-for-loops/" rel="noopener noreferrer"&gt;for loop&lt;/a&gt;and an inner &lt;a href="https://www.pynerds.com/python-while-loop/" rel="noopener noreferrer"&gt;while loop&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
def insertion_sort(lst):

   for i in range(1, len(lst)):
      j = i
      while (j &amp;gt; 0) and lst[j-1] &amp;gt; lst[j]:
         lst[j-1], lst[j] = lst[j], lst[j-1] #swap the elements
         j -=1

#sort a list
L = [99, 9, 0, 2, 1, 0, 1, 100, -2, 8, 7, 4, 3, 2]

insertion_sort(L)
print("The sorted list is: ", L)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;insertion_sort()&lt;/code&gt; function above, does not return any value because the input list is being sorted &lt;strong&gt;in-place&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;For&lt;/code&gt;loops are useful when we know in advance the number of iterations needed  and in contrast, &lt;code&gt;while&lt;/code&gt; loops are more suitable in cases where we do not know in advance the number of iterations to be performed. The fitness of each of the two loops is clearly shown in the above implementation of insertion sort.  Using an inner &lt;code&gt;while&lt;/code&gt;loop ensures that we can efficiently get out of the loop after the element is placed at its position without using extra conditional checks. &lt;/p&gt;

&lt;h3&gt;
  
  
  Descending insertion sort
&lt;/h3&gt;

&lt;p&gt;To sort the list elements in descending order using insertion sort, we simply need to change a single statement in the &lt;code&gt;insertion_sort()&lt;/code&gt; function and actually just a single character.&lt;/p&gt;

&lt;p&gt;Changing the &lt;code&gt;&amp;gt;&lt;/code&gt; character in the second condition of the while loop to&lt;code&gt;&amp;lt;&lt;/code&gt; character will make the algorithm to sort the elements in descending order i.e we need to change the statement from&lt;code&gt;while (j &amp;gt; 0) and lst[j-1] &amp;gt; lst[j]:&lt;/code&gt; to  &lt;code&gt;while (j &amp;gt; 0) and lst[j-1] &amp;lt; lst[j]:&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;descending insertion sort&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
def insertion_sort(lst):

   for i in range(1, len(lst)):
      j = i
      while (j &amp;gt; 0) and lst[j-1] &amp;lt; lst[j]: #changed &amp;gt; to &amp;lt;
         lst[j-1], lst[j] = lst[j], lst[j-1] #swap the elements
         j -=1

#sort a list
L = [99, 9, 0, 2, 1, 0, 1, 100, -2, 8, 7, 4, 3, 2]

insertion_sort(L)
print("The sorted list is: ", L)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Algorithm analysis
&lt;/h2&gt;

&lt;p&gt;The running time complexities of insertions sort are as shown below:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;*&lt;em&gt;best case - *&lt;/em&gt; &lt;code&gt;O(n)&lt;/code&gt;, this is when the list is already sorted.&lt;/li&gt;
&lt;li&gt;*&lt;em&gt;Average case *&lt;/em&gt; - &lt;code&gt;O(n2)&lt;/code&gt;, this is when the list is randomly sorted.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Worst case&lt;/strong&gt; - &lt;code&gt;O(n2&lt;/code&gt;), When the list is reverse sorted.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Applications of insertion sort
&lt;/h2&gt;

&lt;p&gt;The following list outlines cases where insertion sort may be suitable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When the dataset is not very large in size.&lt;/li&gt;
&lt;li&gt;When the elements are almost sorted.&lt;/li&gt;
&lt;li&gt;When simplicity and stability are needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Insertion sort is relatively more performant compared to other basic sorting algorithm such as bubble sort or selection sort. However, its&lt;code&gt;O(n2)&lt;/code&gt;  average and worst running time makes it limited compared to other sorting algorithms such as &lt;strong&gt;quicksort&lt;/strong&gt; or &lt;strong&gt;mergesort&lt;/strong&gt;. It is, therefore, more suitable when sorting small sets of data.&lt;/p&gt;


&lt;h3&gt;Related articles&lt;/h3&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/implement-stack-data-structure-in-python/" rel="noopener noreferrer"&gt;Implement Stack data structure in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/implement-queue-data-structure-in-python/" rel="noopener noreferrer"&gt;Implement Queue data structure in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/implement-fixed-length-stack-in-python/" rel="noopener noreferrer"&gt;Implement Fixed-length stack in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/double-ended-queue-in-python/" rel="noopener noreferrer"&gt;Double-ended Queue in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/doubly-linked-list-in-python/" rel="noopener noreferrer"&gt;Doubly-Linked List in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/implement-inorder-tree-traversal-python/" rel="noopener noreferrer"&gt;Implement Inorder Tree Traversal - Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/implement-bubble-sort-algorithm-in-python/" rel="noopener noreferrer"&gt;Implement bubble sort algorithm in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/implement-selection-sort-in-python/" rel="noopener noreferrer"&gt;Implement selection sort in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Python Function Scope</title>
      <dc:creator>Main</dc:creator>
      <pubDate>Mon, 15 Apr 2024 01:08:35 +0000</pubDate>
      <link>https://forem.com/mainpynerds/python-function-scope-2hap</link>
      <guid>https://forem.com/mainpynerds/python-function-scope-2hap</guid>
      <description>&lt;p&gt;When you use a name in a Python program such as variable name function name,etc,  Python creates, changes or looks up the name in a namespace.  A namespace is the complete list of names  that exists in a given context.&lt;/p&gt;

&lt;p&gt;There are two types of namespaces, &lt;strong&gt;global namespace&lt;/strong&gt; and local &lt;strong&gt;namespace&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The scope of an object determines the locations in the program where it can be accessed, by default, objects are only accessible from within the namespace that they occur. Objects in the global namespace are accessible from anywhere in the program, this are the names that are declared at the top level of a module or a script i.e not inside a function, a class, etc. On the other hand,  names  declared inside a block such as a function are local to that block and are only accessible within the block.&lt;/p&gt;

&lt;p&gt;When we define a function, Python sets up a &lt;strong&gt;local namespace&lt;/strong&gt; for the function. Any object declared inside the function will only be accessible  within the function, the object is said to be local to that function. Trying to access local objects outside their scope will raise a &lt;code&gt;NameError&lt;/code&gt;. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def demo():
    x = 100
    print(x)

demo()
//100
print(x)
//NameError: name 'x' is not defined

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Objects inside a function are localized such that they will not crash with objects with similar names outside that function.This allows same name to be used for different objects in different scopes without causing conflicts.&lt;/p&gt;

&lt;p&gt;If a function declares a name that also exists in the global namespace, the local name takes precedence over the global name and overwrites it only inside that function. Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
x = 200
def demo():
    x = 100
    print(x)

demo()
//100
print(x)
//200

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example,  there are two distinct variables with a name &lt;code&gt;x&lt;/code&gt;, one in the global namespace with a value of &lt;code&gt;200&lt;/code&gt;and another in function demo's local namespace with a value of &lt;code&gt;100&lt;/code&gt;. The value of &lt;code&gt;x&lt;/code&gt;is, therefore,  determined by  the location where we are using it. Making any changes to the&lt;code&gt;'x'&lt;/code&gt; inside the function demo does not affect in any way the value of the &lt;code&gt;'x'&lt;/code&gt; outside its scope.&lt;/p&gt;

&lt;h2&gt;
  
  
  Name Resolution, The LEGB Rule
&lt;/h2&gt;

&lt;p&gt;When we mention an object by name, the Python interpreter follows an inside-out approach in order to identify the object we are referring to. This approach is often referred to as the LEGB rule, which stands for Local, Enclosing, Global, Built-in. This rule can be summarized as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Local, first&lt;/strong&gt; : Look for this name first in the local namespace and use local version if available. If not, go to higher namespace.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enclosing, second&lt;/strong&gt; : If the current function is enclosed within another function, look for the name in that outer function. If not, go to higher namespace.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Global, third&lt;/strong&gt; : Look for the name in the objects defined at global namespace&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built-in,last&lt;/strong&gt; : Finally, look for the variable among Python’s built-in names.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1683457144%2FLocal_500_300_px_ogg7z5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1683457144%2FLocal_500_300_px_ogg7z5.png" alt="LEGB rule"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If the interpreter goes through all the 4 stages and does not locate the name, a &lt;code&gt;NameError&lt;/code&gt;is raised, of course if the operation was not an assignment operation in which case an object with that name will be created in the local scope instead of raising the error. &lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
x = 200
def demo():
    x = 300
    def inner():
        print(x)
    inner()

demo()
//300

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above case, in the call to print&lt;code&gt;x&lt;/code&gt;, the interpreter fails to find an object with a name &lt;code&gt;x&lt;/code&gt; in the function &lt;code&gt;inner&lt;/code&gt;'s  scope, it moves outward to the enclosing function in which case it finds an&lt;code&gt;'x'&lt;/code&gt; with a value of &lt;code&gt;300&lt;/code&gt;thus terminating the search. If still an object with a name &lt;code&gt;'x'&lt;/code&gt;was not located in the enclosing function &lt;code&gt;'demo'&lt;/code&gt;,  the global&lt;code&gt;x&lt;/code&gt;with a value of &lt;code&gt;200&lt;/code&gt;would have been returned. &lt;/p&gt;

&lt;p&gt;More Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
x = 500
def demo():
   print(x)
   x = 300
   print(x)

demo()
//500
//300
def demo2():
   y = 400
   def inner():
       print(x + y)
   inner()

demo2()
//900

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Global Statement
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;global&lt;/code&gt; statement is the only thing  that is capable of transforming a name defined inside a function to  a global name. This means that the name will behave just like names defined in the global namespace and will be accessible from anywhere in the program.&lt;/p&gt;

&lt;p&gt;Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
def demo():
   global x
   x = 200

demo()
print(x)
//200

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a global name exists similar to the name specified in the global statement, any modifications done to the object it identifies will take effect at a global level. Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
x = 100
def demo():
    global x
    x = 500

demo()
print(x)
//500

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To declare multiple global names in one global statement, we use the global keyword followed by the comma separated names, example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
def demo():
   global x, y, z
   x = 4
   y = 3
   z = x + y

demo()
print(x, y, z)
//4, 3, 7

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While the global statement can be useful at times,  it can make code mor obscured as it can make it difficult to keep track of the global names. It should, therefore, be avoided whenever possible, after all names inside a function are made local to that function by default because it is the best policy. We can Instead,  pass global values as function arguments and then return the modified values.&lt;/p&gt;

&lt;h2&gt;
  
  
  The nonlocal Statement
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;nonlocal&lt;/code&gt;statement is a close cousin of the &lt;code&gt;global&lt;/code&gt;statement. While the &lt;code&gt;global&lt;/code&gt;statement makes a name available at global level,  the  &lt;code&gt;nonlocal&lt;/code&gt;statement makes a name available to the &lt;strong&gt;enclosing function's scope&lt;/strong&gt;. This also allows the nested function to make changes to variables defined in the enclosing function. Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
def demo():
    x = 400
    def inner():
        nonlocal x
        x = 600
    inner()
    print(x)

demo()
//600
def demo2():
    def inner():
        nonlocal y 
        y = 500
    inner()
    print(y)

demo2()
//500

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: We cannot use the &lt;code&gt;nonlocal&lt;/code&gt;statement with a top level function, trying this will raise a &lt;code&gt;SyntaxError&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
def demo():
    nonlocal y
    y = 100

demo()
//SyntaxError: no binding for nonlocal 'y' found

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h3&gt;Related articles&lt;/h3&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/introduction-to-functions-in-python/" rel="noopener noreferrer"&gt;Introduction to Functions in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/python-lambda-functions/" rel="noopener noreferrer"&gt;Python Lambda Functions&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/python-filter-function/" rel="noopener noreferrer"&gt;Python filter() Function&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/docstrings-in-python/" rel="noopener noreferrer"&gt;Docstrings in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Bubble sort in Python</title>
      <dc:creator>Main</dc:creator>
      <pubDate>Sun, 14 Apr 2024 17:52:34 +0000</pubDate>
      <link>https://forem.com/mainpynerds/bubble-sort-in-python-4g0b</link>
      <guid>https://forem.com/mainpynerds/bubble-sort-in-python-4g0b</guid>
      <description>&lt;pre&gt;
&lt;code&gt;#Optimized bubble sort
def bubble_sort(lst):

  swapped = True
  c = 0
  while swapped == True:
    swapped = False
    for j in range(len(lst)-1):  
      
      if(lst[j]&amp;gt;lst[j+1]):
        lst[j], lst[j + 1] = lst[j + 1], lst[j] #swap the elements
        swapped = True
      c +=1
  return c

#sort a list
L = [9, 0, 2, 1, 0, 1, 100, -2, 8, 7, 4, 3, 2]

bubble_sort(L)  
print("The sorted list is: ", L)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Bubble sort is the most basic sorting algorithm. Its simplicity makes it suitable for introducing computer science students to sorting algorithms. However, it has an average and worst case running time of &lt;code&gt;O(n&lt;sup&gt;2&lt;/sup&gt;)&lt;/code&gt;, making it highly inefficient for sorting medium to large dataset.&lt;/p&gt;

&lt;p&gt;Bubble sort is highly limited compared to other sorting algorithms and, therefore,  not suitable for practical environments beyond educational ones. &lt;/p&gt;

&lt;p&gt;Despite its limitations, understanding the operation of bubble sort is essential for you to understand how more advanced sorting algorithms works.&lt;/p&gt;

&lt;p&gt;In the following parts we will understand how the bubble sort algorithm operates and how to implement it in Python.&lt;/p&gt;

&lt;h2&gt;Bubble sort Algorithm description&lt;/h2&gt;

&lt;p&gt;In bubble sort algorithm, each pair of adjacent elements are compared and only swapped if they are not in order. That is , if the first element in the pair is larger than the other element, the elements are swapped.&lt;/p&gt;

&lt;p&gt;The swapping of elements happens&lt;strong&gt; in-place&lt;/strong&gt; meaning that the original list gets modified.&lt;/p&gt;

&lt;p&gt;If we have a &lt;strong&gt;list &lt;/strong&gt;of &lt;strong&gt;n &lt;/strong&gt;elements, the bubble sort algorithm can be performed through the steps shown below:&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;Compare the first element with the next element after it.&lt;/li&gt;
    &lt;li&gt;If the first element is greater:
    &lt;ul&gt;
        &lt;li&gt;Swap the two elements.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;Move to the next pair of elements in the list.&lt;/li&gt;
    &lt;li&gt;Repeat step1 -3 until the end of the list is reached.&lt;/li&gt;
    &lt;li&gt;Once no more swaps are needed, the list is sorted.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With the above steps,  the largest elements gradually moves&lt;strong&gt; &lt;/strong&gt;to the end of the list until the list is sorted.&lt;/p&gt;

&lt;h2&gt;Direct Implementation&lt;/h2&gt;

&lt;p&gt;To implement bubble sort, you can use nested loops, the following example shows how we can achieve this with &lt;a href="https://www.pynerds.com/python-for-loops/"&gt;for &lt;/a&gt;loops:&lt;/p&gt;

&lt;p&gt;with nested for loops &lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;def bubble_sort(lst):

  for i in range(len(lst)-1):
    for j in range(len(lst)-1):  

      if(lst[j]&amp;gt;lst[j+1]):
        lst[j], lst[j + 1] = lst[j + 1], lst[j] #swap the elements

#sort a list
L = [9, 0, 2, 1, 0, 1, 100, -2, 8, 7, 4, 3, 2]

bubble_sort(L)  
print("The sorted list is: ", L)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The&lt;code&gt; bubble_sort() &lt;/code&gt;function does not return any value because the sorting happens to the original list.&lt;/p&gt;

&lt;p&gt;As show in the above example, nested for loops provides a much direct way of implementing the bubble sort algorithm, but we can also use nested &lt;a href="https://www.pynerds.com/python-while-loop/"&gt;while&lt;/a&gt; loops to achieve the same, as shown below.&lt;/p&gt;

&lt;p&gt;with while loops &lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;def bubble_sort(lst):

  i = 0
  while i &amp;lt;  len(lst):
    j = 0
    while j &amp;lt; len(lst)-1:
      if(lst[j]&amp;gt;lst[j+1]):
        lst[j], lst[j + 1] = lst[j + 1], lst[j]
      j += 1
    i += 1

L = [9, 7, 1, 2, 4, 1, 3, 0, 6, 5, 8]
bubble_sort(L)  
print("The sorted list is: ", L)&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Optimized Implementation&lt;/h2&gt;

&lt;p&gt;The previous implementation of bubble sort has one avoidable performance inefficiency. This is because whether the list is already sorted, not sorted or reverse sorted, the algorithm still finishes with the worst-case running time of &lt;code&gt;O(n&lt;sup&gt;2&lt;/sup&gt;)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Note that if the algorithm moves through the entire list without performing the  swap operation on any pair of elements, it means that the list is already sorted. We can, therefore, optimize bubble sort to avoid performing unnecessary comparisons by defining an intermediate variable to check whether a swap operation has taken place or not.&lt;/p&gt;

&lt;p&gt;optimized bubble sort&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;def bubble_sort(lst):

  swapped = True
  c = 0
  while swapped == True:
    swapped = False
    for j in range(len(lst)-1):  
      
      if(lst[j]&amp;gt;lst[j+1]):
        lst[j], lst[j + 1] = lst[j + 1], lst[j] #swap the elements
        swapped = True
      c +=1
  return c

#sort a list
L = [9, 0, 2, 1, 0, 1, 100, -2, 8, 7, 4, 3, 2]

bubble_sort(L)  
print("The sorted list is: ", L)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Optimized bubble sort has a best case running time of &lt;code&gt;O(n)&lt;/code&gt;, this is is when the list is already in a sorted state. It still has an average and worst case running time of &lt;code&gt;O(n&lt;sup&gt;2&lt;/sup&gt;)&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;Bubble sort's space and time complexity&lt;/h3&gt;

&lt;h4&gt;space complexity&lt;/h4&gt;

&lt;p&gt;Bubble sort has a space complexity of O(1) this is because no extra lists are used in its internal logic. The sorting happens directly on the input list without the use of intermediate lists.&lt;/p&gt;

&lt;h4&gt;Time complexity&lt;/h4&gt;

&lt;p&gt;The &lt;strong&gt;unoptimized&lt;/strong&gt; version of bubble sort has a time complexity of O(n&lt;sup&gt;2&lt;/sup&gt;) regardless of whether the input list is &lt;strong&gt;already sorted&lt;/strong&gt;, &lt;strong&gt;not sorted &lt;/strong&gt;or &lt;strong&gt;reverse sorted&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;On the other hand, the time complexity cases of the &lt;strong&gt;optimized &lt;/strong&gt;version are as highlighted below:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;
&lt;strong&gt;Best-O(n) &lt;/strong&gt;- This happens when the input list is already sorted as we simply traverse through the list once.&lt;/li&gt;
    &lt;li&gt;
&lt;strong&gt;Average-O(n&lt;sup&gt;2&lt;/sup&gt;) &lt;/strong&gt;- When the input list is not sorted and the elements are in arbitrary order.&lt;/li&gt;
    &lt;li&gt;
&lt;strong&gt;Worst&lt;/strong&gt;-&lt;strong&gt;O(n&lt;sup&gt;2&lt;/sup&gt;) &lt;/strong&gt;- When the input list is reverse sorted and, therefore, the swap operation happens with every comparison.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Related articles&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/introduction-to-data-structures-algorithms/"&gt;Introduction to Data Structures &amp;amp; Algorithms&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/implement-stack-data-structure-in-python/"&gt;Implement Stack data structure in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/implement-queue-data-structure-in-python/"&gt;Implement Queue data structure in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/implement-fixed-length-stack-in-python/"&gt;Implement Fixed-length stack in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/implement-inorder-tree-traversal-python/"&gt;Implement Inorder Tree Traversal - Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Selection sort in Python</title>
      <dc:creator>Main</dc:creator>
      <pubDate>Sun, 14 Apr 2024 17:43:34 +0000</pubDate>
      <link>https://forem.com/mainpynerds/selection-sort-in-python-1lb2</link>
      <guid>https://forem.com/mainpynerds/selection-sort-in-python-1lb2</guid>
      <description>&lt;p&gt;Selection sort is a simple comparison-based sorting algorithm. It is relatively inefficient compared to other sorting algorithms making it not suitable for sorting large sets of data. However, understanding how it works is a foundational step for understanding more sophisticated sorting algorithms and generally how sorting algorithms operates.&lt;/p&gt;

&lt;p&gt;This algorithm has an &lt;strong&gt;average &lt;/strong&gt;and &lt;strong&gt;worst &lt;/strong&gt;time complexities of &lt;strong&gt;O(n&lt;sup&gt;2&lt;/sup&gt;)&lt;/strong&gt; where &lt;code&gt;n&lt;/code&gt; is the number of elements in the array/list.&lt;/p&gt;

&lt;p&gt;Selection sort works &lt;strong&gt;in-place&lt;/strong&gt; meaning that it reorders the elements in the original list rather than creating a new list. This makes it &lt;strong&gt;memory-efficient&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;Algorithm Description&lt;/h2&gt;

&lt;p&gt;In selection sort, an array/list is divided into two segments; the  &lt;strong&gt;sorted segment&lt;/strong&gt; on the left and the &lt;strong&gt;unsorted segment &lt;/strong&gt;on the right. Initially, the sorted segment is empty while the unsorted segment consists of the entire list. At each step,  the algorithm &lt;strong&gt;selects &lt;/strong&gt;the smallest unsorted element and exchanges it with the first element of the&lt;strong&gt; unsorted segment&lt;/strong&gt;. This gradually increases the size of the sorted segment while reducing that of the unsorted segment and eventually the entire list becomes sorted.&lt;/p&gt;

&lt;p&gt;The algorithm can be achieved through the following steps:&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;Set &lt;code&gt;MIN&lt;/code&gt; to position &lt;code&gt;0&lt;/code&gt;.&lt;/li&gt;
    &lt;li&gt;Find the smallest element in the list.&lt;/li&gt;
    &lt;li&gt;Swap it with the value at &lt;code&gt;MIN&lt;/code&gt;.&lt;/li&gt;
    &lt;li&gt;Increment &lt;code&gt;MIN&lt;/code&gt;.&lt;/li&gt;
    &lt;li&gt;Repeat steps &lt;code&gt;1-4 &lt;/code&gt;until the list is sorted.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;Example&lt;/h3&gt;

&lt;p&gt;Consider if we start with the following unsorted list.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1713053240%2F39ed33b3-4bcb-47ca-9558-c553b1a1a094_xxdhbn.png" class="article-body-image-wrapper"&gt;&lt;img alt="unsorted list" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1713053240%2F39ed33b3-4bcb-47ca-9558-c553b1a1a094_xxdhbn.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Elements in the sorted segment are in color green while those in the unsorted segment are in red.Two upper arrows will be used to indicate a swap operation.&lt;/p&gt;

&lt;p&gt;At  first step, the unsorted segment consists of the entire list. The &lt;code&gt;MIN &lt;/code&gt;pointer is at the beginning of the list where the  value is &lt;code&gt;4&lt;/code&gt;,  the smallest value in the list is &lt;code&gt;0&lt;/code&gt;, so need to swap 4 and 0.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1713053241%2F29cdc7ae-1d73-42ee-81b4-0243917db157_l0ajtz.png" class="article-body-image-wrapper"&gt;&lt;img alt="compare the first element" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1713053241%2F29cdc7ae-1d73-42ee-81b4-0243917db157_l0ajtz.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the above step &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;4 &lt;/code&gt;are swapped. The sorted segment now contains a single element. In the next step, the smallest unsorted element is&lt;code&gt; 1, &lt;/code&gt;so we need to swap it with the value at the second position which is &lt;code&gt;6&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1713053240%2Fd120b94a-e056-4172-9b7e-7976d9a9f069_bfpzll.png" class="article-body-image-wrapper"&gt;&lt;img alt="compare 6 and 1" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1713053240%2Fd120b94a-e056-4172-9b7e-7976d9a9f069_bfpzll.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And we go on like that with  the next pairs i. &lt;code&gt;6&lt;/code&gt; and &lt;code&gt;3.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1713053240%2F38d52134-a8e8-4b67-bf46-26e4b7111c24_uuz1gl.png" class="article-body-image-wrapper"&gt;&lt;img alt="Compare 6 and 3" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1713053240%2F38d52134-a8e8-4b67-bf46-26e4b7111c24_uuz1gl.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The sorted segment is becoming larger while the unsorted segment is diminishing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1713053240%2F63c40207-cd45-42ab-b491-3b07753da839_z57whi.png" class="article-body-image-wrapper"&gt;&lt;img alt="4 is already sorted" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1713053240%2F63c40207-cd45-42ab-b491-3b07753da839_z57whi.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the above step,&lt;code&gt; 4&lt;/code&gt; is already sorted so we just move to the next element.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1713053240%2F109ebef6-556f-4a4a-882d-8d76a5f21c58_kuuyat.png" class="article-body-image-wrapper"&gt;&lt;img alt="The last step" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdgc50iktu%2Fimage%2Fupload%2Fv1713053240%2F109ebef6-556f-4a4a-882d-8d76a5f21c58_kuuyat.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And finally, after the last step, the list is now sorted.&lt;/p&gt;

&lt;h2&gt;Selection sort implementation&lt;/h2&gt;

&lt;p&gt;The selection sort algorithm can be implemented with nested loops.&lt;/p&gt;

&lt;p&gt;with for loops&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;def selection_sort(lst):
  for i in range(len(lst)):
    smallest = i

    for j in range(i + 1, len(lst)):
      if lst[j] &amp;lt; lst[smallest]:
        smallest = j

    lst[i], lst[smallest] = lst[smallest], lst[i] #swap the elements

#sort a list
L = [99, 9, 0, 2, 1, 0, 1, 100, -2, 8, 7, 4, 3, 2]
selection_sort(L)

print("The sorted list is: ", L)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the above implementation, the sorted segment of the list starts at &lt;code&gt;0&lt;/code&gt; and ends at&lt;code&gt; i &lt;/code&gt;while the unsorted segment starts at&lt;code&gt; i + 1&lt;/code&gt; and ends at&lt;code&gt; n-1&lt;/code&gt; where &lt;code&gt;n&lt;/code&gt; is the length of the list. &lt;/p&gt;

&lt;p&gt;The outer loop traverses through all elements of the list. While inner loop's only traverses the unsorted segment (beginning at i.e &lt;code&gt;i + 1&lt;/code&gt; ) , it finds the position of the smallest unsorted element and assigns it to the &lt;code&gt;smallest &lt;/code&gt;variable. The smallest element is then swapped with the outer loops current value in the&lt;code&gt; lst[i], lst[smallest] = lst[smallest], lst[i]&lt;/code&gt; statement.&lt;/p&gt;

&lt;h4&gt;with nested while loops&lt;/h4&gt;

&lt;p&gt;We can also implement the selection sort algorithm using nested while loops, as shown below:&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;def selection_sort(lst):
  i = 0
  while i &amp;lt; len(lst):

    smallest = i
    j = i + 1
    while j &amp;lt; len(lst):
      if lst[j] &amp;lt; lst[smallest]:
        smallest = j
      j += 1
    
    lst[i], lst[smallest] = lst[smallest], lst[i] #swap the elements
    i += 1

#sort a list
L = [99, 9, 0, 2, 1, 0, 1, 100, -2, 8, 7, 4, 3, 2]

selection_sort(L)
print("The sorted list is: ", L)&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Descending selection sort&lt;/h2&gt;

&lt;p&gt;To make the selection sort algorithm to sort the elements in descending order,  we simply need to change the sign from &lt;code&gt;&amp;lt;&lt;/code&gt; to&lt;code&gt; &amp;gt;&lt;/code&gt; in the comparison line i.e from &lt;code&gt; if lst[j] &amp;lt; lst[smallest]:&lt;/code&gt; . to &lt;code&gt;if lst[j] &amp;gt; lst[smallest]: &lt;/code&gt;.This is as  shown below:&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;#descending selection sort
def selection_sort(lst):
  for i in range(len(lst)):
    smallest = i

    for j in range(i + 1, len(lst)):
      if lst[j] &amp;gt; lst[smallest]:
        smallest = j

    lst[i], lst[smallest] = lst[smallest], lst[i] #swap the elements

#sort a list
L = [99, 9, 0, 2, 1, 0, 1, 100, -2, 8, 7, 4, 3, 2]
selection_sort(L)

print("The sorted list is: ", L)&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Complexity  Analysis&lt;/h2&gt;

&lt;h4&gt;space complexity&lt;/h4&gt;

&lt;p&gt;The selection sort algorithm has a space complexity of&lt;code&gt; O(1)&lt;/code&gt; . This means that it is memory-efficient as it does extra extra memory except for holding the basic variables e.g &lt;code&gt;smallest&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;time complexity&lt;/h4&gt;

&lt;p&gt;The presence of nested loops in the selection sort algorithm implies that it has a time complexity of &lt;code&gt;O(n&lt;sup&gt;2&lt;/sup&gt;)&lt;/code&gt;, this is for both average case and worst case scenarios.&lt;/p&gt;


&lt;h3&gt;Related articles&lt;/h3&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/implement-stack-data-structure-in-python/" rel="noopener noreferrer"&gt;Implement Stack data structure in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/implement-queue-data-structure-in-python/" rel="noopener noreferrer"&gt;Implement Queue data structure in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/implement-fixed-length-stack-in-python/" rel="noopener noreferrer"&gt;Implement Fixed-length stack in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/implement-inorder-tree-traversal-python/" rel="noopener noreferrer"&gt;Implement Inorder Tree Traversal - Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/data-structures/implement-bubble-sort-algorithm-in-python/" rel="noopener noreferrer"&gt;Implement bubble sort algorithm in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

</description>
      <category>python</category>
      <category>programming</category>
      <category>programmers</category>
    </item>
    <item>
      <title>Set methods in Python</title>
      <dc:creator>Main</dc:creator>
      <pubDate>Sun, 07 Apr 2024 12:59:04 +0000</pubDate>
      <link>https://forem.com/mainpynerds/set-methods-in-python-4mnm</link>
      <guid>https://forem.com/mainpynerds/set-methods-in-python-4mnm</guid>
      <description>&lt;h1&gt; &lt;/h1&gt;

&lt;p&gt;A  &lt;code&gt;set&lt;/code&gt; is an abstract data type that represents an unordered collection of unique elements.&lt;/p&gt;

&lt;p&gt;Sets just like lists are mutable meaning that operations such as insertion and deletion can be performed on them in-place and without  creating a new set. &lt;/p&gt;

&lt;p&gt;In Python, sets are represented using the  &lt;code&gt;set &lt;/code&gt;type/class. This class defines a number of methods to support various operations on sets. The operations can be sub-divided into: &lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;
&lt;strong&gt;Elementary operations&lt;/strong&gt; such as insertion, deletion, etc.&lt;/li&gt;
    &lt;li&gt;
&lt;strong&gt;Set operations &lt;/strong&gt;such as union, intersection, difference, etc .&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;Methods for Elementary operations&lt;/h2&gt;

&lt;p&gt;Set, like most data structures, supports basic operations such as Insertion and deletion. This is achieved through several methods defined in the &lt;code&gt;set &lt;/code&gt;class.&lt;/p&gt;

&lt;h4&gt;&lt;code&gt;add()&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;add() &lt;/code&gt;method is used to add a single element to the set. It takes one parameter, which is the element to be added&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;myset.add(x)&lt;/code&gt;&lt;/pre&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;code&gt;x&lt;/code&gt;&lt;/td&gt;
            &lt;td&gt;The element to be added to the set.&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Sets can only contain unique elements thus the operation will have no effect if the element already exists.&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;myset = {1, 2, 3}

#add some elements
myset.add(4)
myset.add(5)

#this has no effect because the elements exists.
myset.add(2)
myset.add(1)

print(myset)&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;&lt;code&gt;clear() &lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;clear()&lt;/code&gt; method takes no argument, it removes all elements present in a set effectively turning it to an empty set.&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;myset.clear()&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;
&lt;code&gt;#a non-empty set
myset = {1, 2, 3, 4}

#remove all elements
myset.clear()
print(myset)&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;&lt;code&gt;copy()&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;The&lt;code&gt; copy()&lt;/code&gt; method is used to create a shallow copy of the set.This means that  the method returns a new set object that contains all the elements of the original set but will not be affected if any changes are made to the original set.&lt;/p&gt;

&lt;p&gt;The method takes does not take any arguments.&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;myset.copy()&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The method returns a new set which is a shallow copy of the original set.&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;myset = {3, 5, 7}

copied = myset.copy()
print(copied)&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;&lt;code&gt;discard()&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;The&lt;code&gt; discard()&lt;/code&gt; method removes an element from the &lt;code&gt;set&lt;/code&gt; if  it is present. It does not raise an exception if  the element is not present.&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;myset.discard(x)&lt;/code&gt;&lt;/pre&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;code&gt;x&lt;/code&gt;&lt;/td&gt;
            &lt;td&gt;The element to be removed.&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;pre&gt;
&lt;code&gt;myset = {1, 3, 5, 6, 7, 8, 9}

#remove an element
myset.discard(6)
myset.discard(8)

print(myset)

#no exception is raised if the element does not exist
myset.discard(10)&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;&lt;code&gt;pop() &lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;pop() &lt;/code&gt;method removes and returns an arbitrary/random element from the set. It raises a &lt;code&gt;KeyError &lt;/code&gt;if the &lt;code&gt;set &lt;/code&gt;is empty.&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;myset.pop()&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The method takes no arguments, it returns the removed arbitrary element.&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;myset = {0, 2, 4, 6, 8, 10}

#remove and return an arbitrary element
print(myset.pop())
print(myset.pop())
print(myset.pop())
print(myset.pop())

print(myset)&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;&lt;code&gt;remove() &lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;remove()&lt;/code&gt; method just like &lt;code&gt;discard() &lt;/code&gt;, removes an element from a set if it is a member. However, if the element is not present, &lt;code&gt;remove()&lt;/code&gt; will raise a &lt;code&gt;KeyError &lt;/code&gt;whereas &lt;code&gt;discard() &lt;/code&gt;will not.&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;myset.remove(x)&lt;/code&gt;&lt;/pre&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;code&gt;x&lt;/code&gt;&lt;/td&gt;
            &lt;td&gt;The element to be removed.&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The method removes element &lt;code&gt;x &lt;/code&gt;from the &lt;code&gt;set &lt;/code&gt;, it raises a &lt;code&gt;KeyError&lt;/code&gt; exception if the element is not present.&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;myset = {1, 3, 5, 6, 7, 8, 9}

myset.remove(6)
myset.remove(8)
print(myset)

#raises an exception
myset.remove(10)&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;&lt;code&gt;update() &lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;The&lt;code&gt; update()&lt;/code&gt;  method  is used to extend a set  with elements from an iterable object. This means elements from the iterable that  are not already present in the set will be added to the set.&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;myset.extend(iterable)&lt;/code&gt;&lt;/pre&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;code&gt;iterable&lt;/code&gt;&lt;/td&gt;
            &lt;td&gt;An iterable object containing the elements to be added to the set.&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;pre&gt;
&lt;code&gt;myset = {1, 3, 5}

#The iterable with the elements
elements = [5, 7, 9, 11]

#add elements to the set
myset.update(elements)
print(myset)&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Methods for set operations &lt;/h2&gt;

&lt;p&gt;Apart from the usual operations, sets also supports operations that are only unique to them. Such operations includes Union, intersection,  Difference, etc.&lt;/p&gt;

&lt;p&gt;In this part we will explore the various methods that are meant for performing set operations.&lt;/p&gt;

&lt;h4&gt;&lt;code&gt;difference()&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;The&lt;code&gt; difference()&lt;/code&gt; method returns the difference of two or more sets as a new set.  The returned set contains only those items from the first set that are not present in the other sets.&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;set1.difference(set2 [,set3] [, set4], ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The method takes in arbitrary number of sets as arguments and returns a &lt;code&gt;set &lt;/code&gt;with the elements of the original set(&lt;code&gt;set1&lt;/code&gt;) which are not present in the input sets. Note that if multiple sets are given as inputs,  they will be combined into one set before the operation.&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;set1 = {1, 3, 5, 7, 9, 11}
set2 = {3, 9, 13}
set3 = {7, 9, 11}

diff = set1.difference(set2, set3)
print(diff)&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;&lt;code&gt;difference_update()&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;The&lt;code&gt; difference_update() &lt;/code&gt;method is similar to the &lt;code&gt;difference() &lt;/code&gt;method in that  both returns those elements from one set that are not present in the other(s). However, the &lt;code&gt; difference_update() &lt;/code&gt;method updates the original set by removing elements found in the second set rather than creating a new set.&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;set1.difference_update(set2 [,set3][, set4]...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The method removes elements from &lt;code&gt;set1 &lt;/code&gt;that are present in the input sets(&lt;code&gt;set2&lt;/code&gt;, &lt;code&gt;set3&lt;/code&gt;, etc).&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;set1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
set2 = {0, 2, 4}
set3 = {6, 8}

set1.difference_update(set2, set3)
#elements are removed from the original set
print(set1)&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;&lt;code&gt;intersection()&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;The&lt;code&gt; intersection()&lt;/code&gt; method returns the intersection of two sets as a new set. This is a set that contains all the elements that are common between  two given sets.&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;set1.intersection(set2 [,set3] [,set4]...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The method returns elements that are common in both the original &lt;code&gt;set &lt;/code&gt;and the input &lt;code&gt;set&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;set1 = {1, 2, 3, 4, 5}
set2 = {1, 3, 5, 7, 9}

result = set1.intersection(set2)
print(result)&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;&lt;code&gt;intersection_update()&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;This method is just like the&lt;code&gt; intersection() &lt;/code&gt;method except that it  does not create a new set, instead, it updates the original set.  &lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;s1 = {1,2,3,4,5} 
s2 = {3,4,5,6,7} 
s1.intersection_update(s2)

print(s1)&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;&lt;code&gt;symmetric_difference() &lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;The&lt;code&gt; symmetric_difference() &lt;/code&gt;method returns a new set with elements that are in either of the sets, but not in both.&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;set1.symmetric_difference(set2) &lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;
&lt;code&gt;s1 = {'a', 'b', 'c', 5}
s2 = {3, 5, 7, 'c'}

result = s1.symmetric_difference(s2)
print(result)&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;&lt;code&gt;symmetric_difference_update()&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;Just like &lt;code&gt;symmetric_difference() &lt;/code&gt;except that it updates the original list rather than creating a new one.&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;set1.symmetric_difference_update(set2) &lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;
&lt;code&gt;s1 = {'a', 'b', 'c', 5}
s2 = {3, 5, 7, 'c'}

s1.symmetric_difference_update(s2)
print(s1)&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;&lt;code&gt;isdisjoint()&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;isdisjoint() &lt;/code&gt;method in checks whether two sets have a common item or not. If there are common elements in sets, it returns &lt;code&gt;False &lt;/code&gt;otherwise it will return &lt;code&gt;True&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;set1.isdisjoint(set2)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It returns &lt;code&gt;True &lt;/code&gt;if there is no any common element between &lt;code&gt;set1 &lt;/code&gt;and &lt;code&gt;set2&lt;/code&gt;, otherwise &lt;code&gt;False&lt;/code&gt;. &lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;s1 = {'a', 'b', 'c'}
s2 = {1, 2, 3, 4}
s3 = {0, 2, 4}

print(s1.isdisjoint(s2))
print(s1.isdisjoint(s3))
print(s2.isdisjoint(s3))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;issubset() &lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;issubset()&lt;/code&gt; method checks if all elements of a set are present in another set (passed as an argument). &lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;set1.issubset(set2)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It returns &lt;code&gt;True &lt;/code&gt;if all elements in &lt;code&gt;set1 &lt;/code&gt;are present in &lt;code&gt;set2&lt;/code&gt;, otherwise &lt;code&gt;False&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;evens = {0, 2, 4, 6, 8}
odds = {1, 3, 5, 7, 9}
digits = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

print(evens.issubset(digits))
print(odds.issubset(digits))
print(evens.issubset(odds))&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;&lt;code&gt;issuperset()&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;The&lt;code&gt; issuperset()&lt;/code&gt; method checks whether the current set is a superset of the input set. That is if all the elements in the input set are contained within the current set. &lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;set1.issuperset(set2)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The method returns &lt;code&gt;True &lt;/code&gt;if all elements of &lt;code&gt;set2 &lt;/code&gt;are in &lt;code&gt;set1&lt;/code&gt;, otherwise &lt;code&gt;False&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;evens = {0, 2, 4, 6, 8}
odds = {1, 3, 5, 7, 9}
digits = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

print(digits.issuperset(evens))
print(digits.issuperset(odds))
print(evens.issuperset(odds))&lt;/code&gt;&lt;/pre&gt;


&lt;h3&gt;Related articles&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/set-add-method-in-python/"&gt;set.add() method in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/set-clear-method-in-python/"&gt;set.clear() method in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/set-difference-method-in-python/"&gt;set.difference() method in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/set-difference-update-method-in-python/"&gt;set.difference_update() method in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/set-intersection-method-in-python/"&gt;set.intersection() method in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/set-intersection-update-in-python/"&gt;set.intersection_update() in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/set-discard-method-in-python/"&gt;set.discard() method in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="/set-pop-method-in-python/"&gt;set.pop() method in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/set-remove-method-in-python/"&gt;set.remove() method in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/set-isdisjoint-method-in-python/"&gt;set.isdisjoint() method in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/set-issubset-method-in-python/"&gt;set.issubset() method in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>programming</category>
      <category>programmers</category>
    </item>
    <item>
      <title>Instance, Class and Static methods in Python</title>
      <dc:creator>Main</dc:creator>
      <pubDate>Sun, 07 Apr 2024 12:51:37 +0000</pubDate>
      <link>https://forem.com/mainpynerds/instance-class-and-static-methods-in-python-2ede</link>
      <guid>https://forem.com/mainpynerds/instance-class-and-static-methods-in-python-2ede</guid>
      <description>&lt;p&gt;Methods are functions that are associated with a particular object or class. The three types of methods are :&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;
&lt;strong&gt;Instance methods&lt;/strong&gt;: These methods are associated with instances of a class and can access and modify the data within an instance.&lt;/li&gt;
    &lt;li&gt;
&lt;strong&gt;Class methods&lt;/strong&gt;: These methods are associated with a class rather than instances.  They are used to create or modify class-level properties or behaviors.&lt;/li&gt;
    &lt;li&gt;
&lt;strong&gt;Static methods&lt;/strong&gt;: These are utility methods that do not have access to any object-level or class-level data.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Understanding the difference between the 3 types of  methods will be crucial in ensuring that you write classes that  are properly organized, efficient, easy to maintain and which are a close reflection of the real life objects they are being modeled after. &lt;/p&gt;

&lt;p&gt;The following  example shows how each of these methods are defined in a class. We will talk about the technical details in a while.&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;class Example:
    #define an instance method
    def method(self):
        Return "I am an instance method"
    
    #define a class method
    @classmethod
    def class_method(cls):
        return "I am a class method"
    
    #Define a static method
    @staticmethod
    def static_method():
        return "I am a static method"&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Instance Methods&lt;/h2&gt;

&lt;p&gt;Instance methods are functions defined inside a class that perform operations on instances rather than the class itself.&lt;/p&gt;

&lt;p&gt;If you have interacted with Python classes, it is likely that you have encountered and used instance methods. You can easily identify the methods by looking for the  parameter &lt;code&gt;self&lt;/code&gt; in the method definition.&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;#define the class
class Example:
    #Define an instance method
    def method(self):
        return "I am an instance method. I will only work when called by objects of this class!"

#create an object
e = Example()
#call an instance method
print(e.method())&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Instance methods are able to access and modify an instance variables and data. &lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;class Student:

   #Define the constructor
   def __init__(self, name, grade):
       self.name = name  
       self.grade = grade

   #define other instance methods
   def change_grade(self, new_grade):
       self.grade = new_grade 

   def print_info(self):
       print(f"{self.name} is in grade {self.grade}") 

s1 = Student("Bob", 9)

s1.print_info() 

s1.change_grade(10)

s1.print_info()&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt; Note: Calling an instance method from the class itself will raise a &lt;code&gt;TypeError&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;#define the class
class Example:

    #Define an instance method
    def method(self):
        return "I am an instance method. I will only work when called by objects!"

#Try calling an instance method from the class itself. An error is raised!.
print(Example.method())&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;Instance methods cannot modify class level variables&lt;/h4&gt;

&lt;p&gt;Instance methods are only able to access and modify instance variables, which exist only within the scope of an instance of a class. As such, they cannot access or modify class level variables.&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;class Example:
   #Define a class level variable
   x = 10

   #The following method will modify the value of x at instance level rather than at class level
   def modify(self):
      self.x = 1000


print(Example.x)

e = Example()
e.modify()
print(Example.x)&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Class Methods&lt;/h2&gt;

&lt;p&gt;Class methods are methods that are bound to a class rather than to objects. These methods can be called directly from the class itself as well as from the instances. &lt;/p&gt;

&lt;p&gt;Class methods take &lt;code&gt;cls &lt;/code&gt;as the first argument. The &lt;code&gt;cls &lt;/code&gt;argument is a reference to the class, and is used to access class attributes and methods. It is analogous to the &lt;code&gt;self&lt;/code&gt; argument for instance methods.&lt;/p&gt;

&lt;p&gt;We use the &lt;a href="https://www.pynerds.com/python-classmethod-function/"&gt;@classmethod&lt;/a&gt; decorator to define a class method. The syntax is as follows:&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;@classmethod
def method_name(cls):
    #method body&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Class methods  operate on the class itself, rather than on an instances of the class. They are used to provide general functionality for objects of that particular class.&lt;/p&gt;

&lt;p&gt;Consider the following example:&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;class Example:
   #Define a class level variable
   x = 10

   #The following method will modify the value at class level
   @classmethod
   def modify(cls, v):
      """Modify the value of the class level variable x with the new variable v"""
      cls.x = v


print(Example.x)

#Call class method from the class itself
Example.modify(100)
print(Example.x)

#call class method from an instance
e = Example()
e.modify(1000)
print(Example.x)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The following example shows how we can keep a count of all the active instances of a class using class method.&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;#Define the class
class Example:
   
   #The variable to keep the count
   count = 0

   def __init__(self):
      self.increase_count() #Call increas count each time a new object is created.
   
   @classmethod
   def increase_count(cls):
       """This method increases the global level variable, 'count' """
       cls.count +=1
  
   @classmethod
   def get_count(cls):
       return cls.count

#The following exampls demonstrate the methods at work.

print(Example.get_count())

e1 = Example()
print(Example.get_count())

e2 = Example()
e3 = Example()
print(Example.get_count())

e4 = Example()
e5 = Example()
print(e5.get_count())
   &lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Static methods&lt;/h2&gt;

&lt;p&gt;From the above discussions, instance methods operate on instances, while class method operate on the class itself.&lt;/p&gt;

&lt;p&gt;Static methods,  as the name suggests are just static. They belong to a class but the do not have access to class or instance variables. They are simply meant for providing utility services that are not class or instance specific.&lt;/p&gt;

&lt;p&gt;Note: While instance method  and class methods always take &lt;code&gt;self&lt;/code&gt;,  &lt;code&gt;cls &lt;/code&gt;as their first arguments respectively. Static methods do not take any mandatory argument as the first argument. This is because they are not bound to either the class or instances and are simply called directly.&lt;/p&gt;

&lt;p&gt;Static methods are defined using the &lt;a href="https://www.pynerds.com/python-staticmethod-function/"&gt;@staticmethod&lt;/a&gt; decorator.  The syntax is as follows:&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;@staticmethod
def method_name(params):
   #method body&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;
&lt;code&gt;class Example:

   @staticmethod
   def method():
      print("I am a static method.")

Example.method()

e = Example()
e.method()&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As shown above, static methods can be called from the class itself as well as from the instances.&lt;/p&gt;

&lt;p&gt;Consider if we have the class &lt;strong&gt;Rectangle&lt;/strong&gt;, we can define a utility/static methods for calculating the area and the perimeter.&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;#define the class

class Rectangle:
   
   def __init__(self, w, l):
       self.width = w
       self.length = l

   #define some instance methods
   def area(self):
       """This method will call the static method 'calculate_area' """
       return self.calculate_area(self.width, self.length)

   def perimeter(self):
      """This method will call the static method 'calculate_perimeter' """
      return self.calculate_perimeter(self.width, self.length)

   #Define utilty methods that are accessible from the class as well as instances
   @staticmethod
   def calculate_area(w, l):
       return w * l

   @staticmethod
   def calculate_perimeter(w, l):
       return 2 * ( w + l)

#Use utility methods from the class
print(Rectangle.calculate_area(7, 4))
print(Rectangle.calculate_perimeter(7, 4))

#from instances
r = Rectangle(20, 30)
print(r.area())
print(r.perimeter())

r2 = Rectangle(100, 50)
print(r2.area())
print(r2.perimeter())
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;ol&gt;
    &lt;li&gt;Instance methods operate at instance level. They take &lt;code&gt;self &lt;/code&gt;as their first argument&lt;/li&gt;
    &lt;li&gt;Class methods operate at class level, they have access to class variables. They are defined using the @classmethod decorator.  They take &lt;code&gt;cls &lt;/code&gt;as the first argument.&lt;/li&gt;
    &lt;li&gt;Static methods are utility methods, they do not have access to class or instance variables. They are defined using the @staticmethod decorator and they do not take any mandatory first argument. &lt;/li&gt;
&lt;/ol&gt;


&lt;h3&gt;Related articles&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/pythons-applications-in-modern-software-development/"&gt;Python's Applications in Modern Software Development&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/python-classmethod-function/"&gt;Python classmethod() Function&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/python-staticmethod-function/"&gt;Python staticmethod() Function&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/python-static-or-class-variables/"&gt;Python static or class variables&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="/introduction-to-object-oriented-programming/"&gt;Introduction to Object Oriented Programming&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/python-classes-init-method/"&gt;Python classes &lt;strong&gt;init&lt;/strong&gt;() method&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/python-classes-str-method/"&gt;Python Classes &lt;strong&gt;str&lt;/strong&gt;() Method&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/difference-between-function-and-method-in-python/"&gt;Difference between function and method in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.pynerds.com/introduction-to-concurrent-programming-in-python/"&gt;Introduction to concurrent programming in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>python</category>
      <category>programmers</category>
    </item>
  </channel>
</rss>
