#!/usr/bin/python3
# ==============================================================
# compare 2 lists of random integers
# ==============================================================
import random
import sys
VERBOSE = False
# --------------------------------------------------------------
# ---- compare list A and B using loops, logic, and indexes
# --------------------------------------------------------------
# ----
# ---- Algorithm: compare lists A and B (one element at a time)
# ----
# ---- sort list A and B
# ----
# ---- loop:
# ----
# ---- if end of list A and B:
# ---- break
# ----
# ---- if end of list A:
# ---- mark the remaining elements on list B as not-in-a
# ---- break
# ----
# ---- if end of list B:
# ---- mark the remaining elements on list A as not-in-b
# ---- break
# ----
# ---- if the current elements in list A and B match
# ---- mark the current elements as in-both-a-and-b
# ---- get the next elements from each list
# ---- continue
# ----
# ---- if element in list A less that element in list B
# ---- mark the current A element as not-in-b
# ---- get next element from list A
# ---- continue
# ----
# ---- if element in list B less that element in list A
# ---- mark the current B element as not-in-a
# ---- get next element from list B
# ---- continue
# ----
# ---- Note: Instead of marking elements, copy then to
# ---- unique lists?
# ----
# --------------------------------------------------------------
def compare_lists(a,b):
in_both = [] # in both A and B lists
in_a_not_b = [] # in A but not B list
in_b_not_a = [] # in B but not A list
a_idx = 0 # list A index
b_idx = 0 # list B index
a_len = len(a) # list A length
b_len = len(b) # list B length
while True:
# ---- end of both lists (A and B)
if a_idx >= a_len and b_idx >= b_len:
break
# ---- end of A list
# ---- append remaining B list elements to
# ---- "in_b_not_a" list
if a_idx >= a_len:
if VERBOSE:
print('end of list A')
while b_idx < b_len:
in_b_not_a.append(b[b_idx])
b_idx += 1
break
# ---- end of B list
# ---- append remaining A list elements to
# ---- "in_a_not_b" list
if b_idx >= b_len:
if VERBOSE:
print('end of list B')
while a_idx < a_len:
in_a_not_b.append(a[a_idx])
a_idx += 1
break
# ---- compare an element from each list (A and B)
if VERBOSE:
print('compare an element from each list')
if a[a_idx] == b[b_idx]:
in_both.append(a[a_idx])
a_idx += 1
b_idx += 1
continue
elif a[a_idx] < b[b_idx]:
in_a_not_b.append(a[a_idx])
a_idx += 1
continue
elif a[a_idx] > b[b_idx]:
in_b_not_a.append(b[b_idx])
b_idx += 1
continue
# ---- oops! how did we get here?
print()
print('OOPS! How did we get here?')
print()
print(f'a_len = {a_len:3} b_len = {b_len:3}')
print(f'a_idx = {a_idx:3} b_idx = {b_idx:3}')
print()
print(f'in_a_not_b = {in_a_not_b}')
print()
print(f'in_b_not_a = {in_b_not_a}')
print()
print(f'in_both = {in_both}')
print()
print('exit program')
print()
sys.exit()
return(in_both, in_a_not_b, in_b_not_a)
# --------------------------------------------------------------
# ---- compare list A and B using Python sets
# --------------------------------------------------------------
def compare_lists_using_sets(set_a,set_b):
in_both = [] # in both A and B lists
in_a_not_b = [] # in A but not B list
in_b_not_a = [] # in B but not A list
in_both = sorted(list(set_a & set_b))
in_a_not_b = sorted(list(set_a - set_b))
in_b_not_a = sorted(list(set_b - set_a))
return(in_both, in_a_not_b, in_b_not_a)
# --------------------------------------------------------------
# ---- display comparison results
# --------------------------------------------------------------
def display_comparison_results(ab_both, a_only, b_only,
title=None):
# ---- display title?
if title is not None:
print()
print('='*25)
print(title)
print('='*25)
# ---- display in A only list
print()
print('in A list only')
print('--------------')
l = len(a_only)
if l > 0:
for i in range(l):
print(f'{a_only[i]}')
else:
print('none')
# ---- display in B only list
print()
print('in B list only')
print('--------------')
l = len(b_only)
if l > 0:
for i in range(l):
print(f'{b_only[i]}')
else:
print('none')
# ---- display in both lists
print()
print('in both lists')
print('--------------')
l = len(ab_both)
if l > 0:
for i in range(l):
print(f'{ab_both[i]}')
else:
print('none')
# --------------------------------------------------------------
# ---- display lists A and B (side-by-side)
# --------------------------------------------------------------
def display_lists(a, b, title=None):
print()
if title is not None: print(title)
print('Idx A List B List')
print('--- ------ ------')
a_len = len(a)
b_len = len(b)
idx_max = max(a_len,b_len)
for idx in range(idx_max):
if idx < a_len:
a_str = f'{a[idx]:<6}'
else:
a_str = ' '*6
if idx < b_len:
b_str = f'{b[idx]:<6}'
else:
b_str = ' '*6
print(f'{idx:<3} {a_str} {b_str}')
return
# --------------------------------------------------------------
# ---- create random list of positive integers
# --------------------------------------------------------------
def create_random_integer_list(lst_len,
seed_value=None,
min_int=1,
max_int=10):
lst = []
if seed_value is not None: random.seed(seed_value)
for _ in range(lst_len):
lst.append(random.randint(min_int,max_int))
lst.sort()
return lst
# --------------------------------------------------------------
# ---- main
# --------------------------------------------------------------
if __name__ == '__main__':
# ---- create lists random positive integers (sorted)
list1 = create_random_integer_list(11, 123456)
list2 = create_random_integer_list(16, 654321)
display_lists(list1, list2, '----Test Lists-----')
# ---- compare lists using loops, logic, and indexes
ab_both, a_only, b_only = compare_lists(list1,list2)
display_comparison_results(ab_both, a_only, b_only)
# ---- compare lists using Python sets
ab_both, a_only, b_only = compare_lists_using_sets(
set(list1),set(list2))
display_comparison_results(ab_both, a_only, b_only,
'Using Python Sets')