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)))
Related
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
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 - 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))
For example, let's say I have a list:
lst = [1, 2, 3, 3, 4, 3, 5, 6]
Is there any function that returns all the indexes of the 3s?(which would return [2, 3, 5])
I've changed the list in order to build a dictionary of all items that appeared more than once.
from collections import Counter
lst = [1, 2, 3, 3, 4, 3, 5, 2, 6]
# only values that appears more than once
c = Counter(lst) - Counter(set(lst))
res = {}
for i, elem in enumerate(lst):
if elem in c:
item = res.get(elem)
if item:
item.append(i)
else:
res[elem] = [i]
print(res)
output :
{2: [1, 7], 3: [2, 3, 5]}
A better approach is to use defaultdict :
from collections import defaultdict
lst = [1, 2, 3, 3, 4, 3, 5, 2, 6]
d = defaultdict(list)
for i, elem in enumerate(lst):
d[elem].append(i)
print({k: v for k, v in d.items() if len(v) > 1})
output :
{2: [1, 7], 3: [2, 3, 5]}
You can simply use function enumerate(lst)
it returns elements index_number and value.
for example
lst[0] = 1
the case above index_number is 0
and value is 1
so you can just use enumerate function for returning index number using if condition
(returns it when the value is 3)
lst = [1, 2, 3, 3, 4, 3, 5, 6]
lst_result = [i for i, v in enumerate(lst) if v == 3]
print(lst_result)
your outcome will be
[2,3,5]
I was trying to figure out a solution for a similar problem and this is what I came up with.
def locate_index(item_name, list_name):
"""Determine the indexes of an item if in a list."""
locations = []
for i in range(len(list_name)):
if list_name[i] == item_name:
locations.append(list_name.index(item_name, i, len(list_name)))
print(locations)
Example:
lst = [1, 2, 3, 3, 4, 3, 5, 6]
list2 = [1, 2, 3, 3, 4, 3, 5, 6, 6, 6, 6]
locate_index(3, lst) ---- a)
locate_index(6, list2) ---- b)
Output
a)
[2, 3, 5]
b)
[7, 8, 9, 10]
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)