How to find the pattern in a list - python

For example,
# list A
A = [1, 2, 3, 3, 4, 4, 4, 5, 6]
# list B
B = [1, 2, 3, 3, 4, 5, 5, 5, 6]
are given, and we have to check if elements of the lists have the pattern of [x, x, y, y, y].
list A should return "True":
[1, 2, 3, 3, 4, 4, 4, 5, 6]
list B should return "False" as '4' intercepts in the middle: [1, 2, 3, 3, 4, 5, 5, 5, 6]

Just check every possible subarray of length 5 for the pattern. Straightforward way would be:
a = [1, 2, 3, 3, 4, 4, 4, 5, 6]
b = [1, 2, 3, 3, 4, 5, 5, 5, 6]
def is_pattern(alist):
for i in range(0, len(alist) - 4):
sub = alist[i:i + 5]
if sub[0] == sub[1] and (sub[2] == sub[3] == sub[4]):
return True
return False
assert is_pattern(a) is True
assert is_pattern(b) is False

O(n) solution is to iterate the list and count X and Y appearances. Once it breaks the pattern, restore the values accordingly.
Once you find 2 or more appearances you can count Y appearances and return true once it reaches 3.
Otherwise, if count x is less than 2, restore it. If count x is 2 or more but current value doesn't equal to the earlier y, set count x to be count y and set count y to be 1.
a = [1, 2, 3, 3, 3, 4, 4, 4, 5, 6]
b = [1, 2, 3, 3, 4, 5, 5, 5, 6]
c = [1,1,1,1,1]
d = [1, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6]
def is_x_y(arr):
count_x, count_y = 0, 0
x, y = None, None
for val in arr:
if not x:
x = val
if x == val:
count_x += 1
elif count_x >= 2:
if not y:
y = val
if y == val:
count_y +=1
else:
count_x = count_y
x = y
count_y = 1
y = val
else:
count_x = 0
x = None
if count_x >= 2 and count_y == 3:
return True
return False
print(is_x_y(a))
print(is_x_y(b))
print(is_x_y(c))
print(is_x_y(d))
True
False
False
True
if x, x, x, x, x also match your pattern, change the return True condition to also return True on count_x = 5:
if count_x == 5 or (count_x >= 2 and count_y == 3):
return True

Related

Get Indeces of list of numbers Top N, next top N, and last top N

Given that I have a list of numbers:
raw_list = [10, 9, 2, 8, 1, 3, 5, 4, 6, 7,11]
I want to separate it to top N's three times. Which means I want to rank them.
# Top 6 rank as 3
# Next Top 4 rank as 2
# Last Top 1 rank as 1
ranked_list = [3, 3, 2, 3, 1, 2, 2, 2, 3, 3, 3]
What I tried:
sorted(range(len(raw_list)), key=lambda i: raw_list[i])[-2:]
But this only gives indeces of the topmost and not the next topmost value of the list.
Use:
lst = [10, 9, 2, 8, 1, 3, 5, 4, 6, 7, 11]
indices = sorted(range(len(lst)), key=lambda i: lst[i], reverse=True)
ranked_list = [0 for _ in range(len(lst))]
for i, j in enumerate(indices):
if i < 6:
ranked_list[j] = 3
elif i < 6 + 4:
ranked_list[j] = 2
else:
ranked_list[j] = 1
print(ranked_list)
Output
[3, 3, 2, 3, 1, 2, 2, 2, 3, 3, 3]
Here's a different approach which is significantly faster than the accepted answer (if that's important):
Edited to show performance timings between the original and accepted answer because #funnydman wants proof
from timeit import timeit
L = [10, 9, 2, 8, 1, 3, 5, 4, 6, 7, 11]
def func1(list_):
slist = sorted(list_)
result = []
top6 = set(slist[5:])
top4 = set(slist[1:5])
for e in list_:
if e in top6:
result.append(3)
elif e in top4:
result.append(2)
else:
result.append(1)
return result
def func2(list_):
indices = sorted(range(len(list_)), key=lambda i: list_[i], reverse=True)
ranked_list = [0 for _ in range(len(list_))]
for i, j in enumerate(indices):
if i < 6:
ranked_list[j] = 3
elif i < 6 + 4:
ranked_list[j] = 2
else:
ranked_list[j] = 1
return ranked_list
for func in func1, func2:
print(func.__name__, timeit(lambda: func(L)))
Output:
func1 1.3904414890002954
func2 2.388311982000232
IIUC, this will work for you:
import pandas as pd
list(pd.cut(l, bins=[0, 1, 5, 11], labels=[1, 2, 3]))
Output:
[3, 3, 2, 3, 1, 2, 2, 2, 3, 3, 3]

Python program to accept a List,and extract all elements whose frequency is greater than K?

Python - How can I write a python program to accept a List, and extract all elements whose frequency is greater than K? Please advise?
Sample I/O:
Input List:
[4, 6, 4, 3, 3, 4, 3, 4, 6, 6]
Input K:
2
Required Output : [4, 3, 6]
Use a list comprehension:
a = [4, 6, 4, 3, 3, 4, 3, 4, 6, 6]
k = 2
out = [i for i in set(a) if a.count(i) > k]
Use counter in python
list1 = [4, 6, 4, 3, 3, 4, 3, 4, 6, 6]
d = Counter(list1)
new_list = list([item for item in d if d[item] > 1])
print(new_list) #output: [4, 6, 3]
inputs = 0
user_list = []
while inputs < 8:
user_input = int(input("Enter a number: "))
user_list.append(user_input)
inputs += 1
input_list = [4, 6, 4, 3, 3, 4, 6, 6]
input_k = 2
def extract(x, y):
product = []
for i in x:
list_element = i
if list_element > y:
product.append(i)
else:
break
product = list(set(product))
return product
print(extract(user_list, input_k))
print(extract(input_list, input_k))

one line if statement

I have the following code
a = [1, 2, 3, 4, 5, 6]
b = [1, 3, 3, 4, 5, 7]
counter = 0
for x,y in tuple(zip(a, b)):
if x==y:
counter += 1
How do I write that in one line? I tried this counter+= 1 if ((x==y) for (x, y) in tuple(zip(a, b))) else None but it adds 1 to the counter and that's all.
You can leverage True == 1 and False == 0
>>> a = [1, 2, 3, 4, 5, 6]
>>> b = [1, 3, 3, 4, 5, 7]
>>> counter = sum(_a==_b for _a,_b in zip(a,b))
>>> counter
4
Addition over an iterable can be expressed with sum():
counter = sum(1 if x==y else 0 for x,y in zip(a, b))
you can try this,
a = [1, 2, 3, 4, 5, 6]
b = [1, 3, 3, 4, 5, 7]
counter=len([x for x,y in zip(a,b) if x==y])
Another way,
counter=sum(map(lambda x:x[0]==x[1],zip(a,b)))

How to find the max number of times certain digits occur in each list?

For my code, I am trying to find the number of times 4 or 5 occurs in each of the three lists, then printing out the maximum value of the most number of times 4 or 5 occurs.
For example, 4 or 5 occurs in the list AAAAA 8 times, also 8 times for BBB and 5 times for K. So the last line of the code should print 8, but I get an error shown below my code as shown.
Note: I have to make this code using functions with parameters in them. I am familiar with lists, strings, for loops, and some other stuff. So don't show me new stuff cause I'm a beginner.
Code:
AAAAA = [4, 2, 1, 2, 4, 2, 4, 4, 5, 2, 2, 1, 5, 2, 4, 3, 1, 1, 3, 3, 5]
BBB = [5, 2, 1, 2, 4, 5, 4, 4, 1, 2, 2, 2, 4, 4, 4, 3, 1, 2, 3, 3, 2]
K = [4, 1, 2, 1, 2, 1, 2, 5, 1, 1, 1, 1, 4, 2, 2, 1, 5, 1, 3, 4, 1]
x = 4
y = 5
def four_or_five(AAAAA, x):
count = 0
for ele in AAAAA:
if (ele == x):
count = count + 1
return count
def four_or_five(AAAAA, y):
count = 0
for ele in AAAAA:
if (ele == y):
count = count + 1
return count
res = print(four_or_five(AAAAA, x) + four_or_five(AAAAA, y)) ### 4 and 5's in list AAAAA
def four_or_five(BBB, x):
count = 0
for ele in BBB:
if (ele == x):
count = count + 1
return count
def four_or_five(BBB, y):
count = 0
for ele in BBB:
if (ele == y):
count = count + 1
return count
res1 = print(four_or_five(BBB, x)+four_or_five(BBB, y)) ### 4 and 5's in list BBB
def four_or_five(K, x):
count = 0
for ele in K:
if (ele == x):
count = count + 1
return count
def four_or_five(K, y):
count = 0
for ele in K:
if (ele == y):
count = count + 1
return count
res2 = print(four_or_five(K, x)+four_or_five(K, y)) ### 4 and 5's in list K
max_res = max(res,res1,res2) ### Find the max number of times 4 and 5 occurs, which is 8
print(max_res)
_____________________________________________________________
OUTPUT:
8
8
5
TypeError: '>' not supported between instances of 'NoneType' and 'NoneType'
Note: Do not worry about certain digits occuring, 4 or 5 is supposed to be fixed so just leave it as 4 or 5. Also when I say don't alter my code's format, I mean as in leave it as defined functions with parameters in them.
Try to create variables with more descriptive names! Here is the correct code:
def four_or_five(lst):
return lst.count(4) + lst.count(5) # .count() is self explanatory, but below is another way which is more similar to your code:
def alt_four_or_five(lst):
c = 0
for i in lst:
if i == 4 or i == 5:
c += 1
return c
big_list_1 = [4, 2, 1, 2, 4, 2, 4, 4, 5, 2, 2, 1, 5, 2, 4, 3, 1, 1, 3, 3, 5]
big_list_2 = [5, 2, 1, 2, 4, 5, 4, 4, 1, 2, 2, 2, 4, 4, 4, 3, 1, 2, 3, 3, 2]
big_list_3 = [4, 1, 2, 1, 2, 1, 2, 5, 1, 1, 1, 1, 4, 2, 2, 1, 5, 1, 3, 4, 1]
bl1_count = four_or_five(big_list_1)
bl2_count = four_or_five(big_list_2)
bl3_count = four_or_five(big_list_3)
result = max([bl1_count, bl2_count, bl3_count)
print(result) # => 8
If I understand your code, your problem is that you are assigning the variables res, res1 and res2 the return value of the print() function, which is always None. You just need to assing the return value of the function itself.
Also, you don't need to declare functions everytime you use them:
### Instead of:
def func_a(x, y, z):
return x + y + z
x = 1
y = 2
z = 3
func_a(x, y, z)
def func_a(a, b, c):
return a + b + c
a = 4
b = 5
c = 6
func_a(a, b, c)
### Do:
def func_a(x, y, z):
return x + y + z
x = 1
y = 2
z = 3
a = 4
b = 5
c = 6
print(func_a(x, y, z))
print(func_a(a, b, c))
You just need to remove the prints from all the res variables. Because you are trying to print these values, they wont be stored in the variable. Also, 'NoneType' in the error means that the object has nothing stored inside it. Learn more about it here
Code:
AAAAA = [4, 2, 1, 2, 4, 2, 4, 4, 5, 2, 2, 1, 5, 2, 4, 3, 1, 1, 3, 3, 5]
BBB = [5, 2, 1, 2, 4, 5, 4, 4, 1, 2, 2, 2, 4, 4, 4, 3, 1, 2, 3, 3, 2]
K = [4, 1, 2, 1, 2, 1, 2, 5, 1, 1, 1, 1, 4, 2, 2, 1, 5, 1, 3, 4, 1]
x = 4
y = 5
def four_or_five(AAAAA, x):
count = 0
for ele in AAAAA:
if (ele == x):
count = count + 1
return count
def four_or_five(AAAAA, y):
count = 0
for ele in AAAAA:
if (ele == y):
count = count + 1
return count
res = four_or_five(AAAAA, x) + four_or_five(AAAAA, y) ### 4 and 5's in list AAAAA
def four_or_five(BBB, x):
count = 0
for ele in BBB:
if (ele == x):
count = count + 1
return count
def four_or_five(BBB, y):
count = 0
for ele in BBB:
if (ele == y):
count = count + 1
return count
res1 = four_or_five(BBB, x)+four_or_five(BBB, y) ### 4 and 5's in list BBB
def four_or_five(K, x):
count = 0
for ele in K:
if (ele == x):
count = count + 1
return count
def four_or_five(K, y):
count = 0
for ele in K:
if (ele == y):
count = count + 1
return count
res2 = four_or_five(K, x)+four_or_five(K, y) ### 4 and 5's in list K
max_res = max(res,res1,res2) ### Find the max number of times 4 and 5 occurs, which is 8
print(max_res)

Python 2.7 Mode of list without using built-in functions

On Python 2.7 I want to create a function which calculates the Mode of a list without using any built-in functions (e.g, not allowed to use Count)
Try the following function, which does not use sum(), count(), or any built-in function apart from append, to add to a list.
def mode(lst):
sums = {}
for i in lst:
if i in sums:
sums[i]+=1
else:
sums[i] = 1
maxModes = [[-1, -1]]
for j in sums:
if sums[j] > maxModes[0][0]:
maxModes = [[sums[j], j]]
elif sums[j] == maxModes[0][0]:
maxModes.append([sums[j], j])
indices = 0
for k in maxModes:
indices+=1
if indices == 1:
return maxModes[0][1]
else:
thisSum = 0
for l in maxModes:
thisSum+=l[1]
return float(thisSum)/indices
>>> mode([1, 2, 3, 3, 4])
3
>>> mode([1, 2, 3, 3, 4, 4])
3.5
>>> mode([1, 2, 3, 3, 4, 4, 5, 5, 5])
5
>>> mode([1, 2, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6])
5.5
>>> mode([1, 2, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 9, 9, 9])
6.666666666666667
>>> mode([1, 2])
1.5
>>> mode([1])
1
>>> mode([])
-1
>>>
Taking an example of k = [1,2,3,5,3,1,6,3] as a sample list whose mode needs to be calculated
def quickSrt(lst):
if len(lst) < 2:
return lst
pivot = lst[0]
l = quickSrt([x for x in lst[1:] if x < pivot])
r = quickSrt([x for x in lst[1:] if x >= pivot])
return l + [pivot] + r
k = [1,2,3,5,3,1,6,3]
d = {}
for i in k:
if i in d:
d[i] += 1
else:
d[i] = 1
values = [value for key, value in d.items()]
val = quickSrt(values)
for x,y in d.items():
if y == val[-1]:
print(x)

Categories

Resources