If distinct pair of numbers has Odd Product in Python - python

I want to find if the Input String has Odd Product for distinct numbers:
I did this so far:
# To get input string into list of integer
input = [int(i) for i in input.split()]
# to get odd numbers
sequence=filter(lambda i: i % 2, sequence)
I want to use an operation where I can filter distinct odd numbers in a list and multiply until I get odd number and return true if the result is not odd return false.
I am new to lamda and filter.
I want to know how can I do using this in one statement in Python

You can use itertools.accumulate to repeatedly apply a function (e.g. multiplication) to an iterable:
>>> from itertools import accumulate
>>> bool(list(accumulate({int(i) for i in input().split() if int(i) % 2}, int.__mul__))[-1] % 2)
1 2 3 4 5
True

For filtering distinct odd numbers in a list you can use list comprehension along with set(set is used to get distinct values).
input = [int(i) for i in input().split()]
input = list(set([i for i in input if i%2!=0])) # it would give distinct odd values

Related

Comparing floating point numbers and dividing a list to sublists in Python

I need a help. I want to chunk my list with float numbers into sublists to compare two decimal numbers to see if the difference between the consecutive numbers are in the range 10. To more specific, my expectation is to split them for example, those numbers from 70-80 to be in a list, from 80-90 to be in another list, and so on.
Firstly, I sorted my list and then tried to compare two elements, but the result is different from that I want.
Here is my attempt to compare numbers:
mylist = [125.90720268, 122.08697428, 86.70855817, 82.68482956, 75.99304643, 71.92440719, 80.92440719]
chunked_list = []
sort_list = sorted(mylist, key = lambda x:float(x))
curr = [sort_list[0]]
print("sort_list = ", sort_list)
for x in sort_list[1:]:
if abs(x - curr[-1]) < 10:
chunked_list.append(curr)
curr = [x]
else:
curr.append(x)
chunked_list.append(curr) ```
The result is:
[[71.92440719],
[75.99304643],
[80.92440719],
[82.68482956],
[86.70855817, 122.08697428],
[125.90720268]]
while I want to have this result:
[[71.92440719, 75.99304643], [80.92440719, 82.68482956, 86.70855817], [122.08697428, 125.90720268]]
Also, I tried to use math.isclose() function to compare two decimal numbers, but I failed again. I really appreciate that someone tells me where I make a mistake.
You can use itertools.pairwise (or its equivalent recipe if you're using Python of version < 3.10) to iterate through the list in adjacent pairs, and append to the output list a new sub-list if the difference between the pair is greater than 10 while keep appending to the last sub-list the current item:
from itertools import pairwise
output = []
for a, b in pairwise(sorted(mylist)):
if not output or b - a > 10:
output.append([] if output else [a])
output[-1].append(b)
Given your sample input, output becomes:
[[71.92440719, 75.99304643, 80.92440719, 82.68482956, 86.70855817], [122.08697428, 125.90720268]]
Demo: https://replit.com/#blhsing/ImperturbableCrushingAdministrator
EDIT: Since you updated your question with a revised requirement that the numbers should be grouped in multiples of 10, you can append a new sub-list to the output list when the current item divided by 10 is different from the first item of the last sub-list divided by 10:
output = []
for i in sorted(mylist):
if not output or i // 10 != output[-1][0] // 10:
output.append([])
output[-1].append(i)
output becomes:
[[71.92440719, 75.99304643], [80.92440719, 82.68482956, 86.70855817], [122.08697428, 125.90720268]]
Demo: https://replit.com/#blhsing/ElaborateUsedRotation

When making comparison between the elements in a list, how to efficiently iterate and improve the time complexity from O(n^2)?

I have a list where I would like to compare each element of the list with each other. I know we can do that using a nested loop but the time complexity is O(n^2). Is there any option to improve the time complexity and make the comparisons efficient?
For example:
I have a list where I would like to find the difference in digits among each element. Consider a list array=[100,110,010,011,100] where I am trying to find the difference in the digits among each integer. array[0] is same as array[4] (i.e 100 and 100), while array[0] has 1 digit that is different from array[1] (i.e 100 and 110) and array[0] has 3 digits that are different from array[3] (i.e 100 and 011). Assuming similar integers are defined as integers that have either identical or the difference in digits is just 1, I would like to return a list as output, where every element denotes the integers with similar digits (i.e difference in digits <=1).
For the input list array=[100,110,010,011,100], my expected output should be [2,3,2,1,2]. In the output list, the output[0] indicates that array[0] is similar to array[1] and array[4] (i.e similar to 100 , we have 2 other integers 110,100 in the list)
This is my code that works, though very inefficient O(n^2):
def diff(a,b):
difference= [i for i in range(len(a)) if a[i]!=b[i]]
return len(difference)
def find_similarity_int(array):
# write your code in Python 3.6
res=[0]*len(array)
string=[]
for n in array:
string.append(str(n))
for i in range(0,len(string)):
for j in range(i+1,len(string)):
count=diff(string[i],string[j])
if(count<=1):
res[i]=res[i]+1
res[j]=res[j]+1
return res
input_list=['100','110','010','011','100']
output=find_similarity_int(input_list)
print("The similarity metrics for the given list is : ",output)
Output:
The similarity metrics for the given list is : [2, 3, 2, 1, 2]
Could anyone please suggest an efficient way to make the comparison, preferably with just 1 loop? Thanks!
If the values are binary digits only, you can get a O(nxm) solution (where m is the width of the values) using a multiset (Counter from collections). With the count of values in the multiset, add the counts of items that correspond to exactly one bit change in each number (plus the number of duplicates):
from collections import Counter
def simCount(L):
counts = Counter(L) # multiset of distinct values / count
result = []
for n in L:
r = counts[n]-1 # duplicates
for i,b in enumerate(n): # 1 bit changes
r += counts[n[:i]+"01"[b=="0"]+n[i+1:]] # count others
result.append(r) # sum of similars
return result
Output:
A = ['100','110','010','011','100']
print(simCount(A)) # [2, 3, 2, 1, 2]
To avoid the string manipulations on every item, you can convert them to integers and use bitwise operators to make the 1-bit changes:
from collections import Counter
def simCount(L):
bits = [1<<i for i in range(len(L[0]))] # bit masks
L = [int(n,2) for n in L] # numeric values
counts = Counter(L) # multiset n:count
result = []
for n in L:
result.append(counts[n]-1) # duplicates
for b in bits: # 1 bit changes
result[-1] += counts[b^n] # sum similars
return result
A = ['100','110','010','011','100']
print(simCount(A)) # [2, 3, 2, 1, 2]

How to add values into an empty list from a for loop in python?

The given python code is supposed to accept a number and make a list containing
all odd numbers between 0 and that number
n = int(input('Enter number : '))
i = 0
series = []
while (i <= n):
if (i % 2 != 0):
series += [i]
print('The list of odd numbers :\n')
for num in series:
print(num)
So, when dealing with lists or arrays, it's very important to understand the difference between referring to an element of the array and the array itself.
In your current code, series refers to the list. When you attempt to perform series + [i], you are trying to add [i] to the reference to the list. Now, the [] notation is used to access elements in a list, but not place them. Additionally, the notation would be series[i] to access the ith element, but this still wouldn't add your new element.
One of the most critical parts of learning to code is learning exactly what to google. In this case, the terminology you want is "append", which is actually a built in method for lists which can be used as follows:
series.append(i)
Good luck with your learning!
Do a list-comprehension taking values out of range based on condition:
n = int(input('Enter number : '))
print([x for x in range(n) if x % 2])
Sample run:
Enter number : 10
[1, 3, 5, 7, 9]

Highest number in list from input-numbers in Python

def my_max():
#using input to collect number to list
list_a = input("print your list with numbers: ").split(",")
# Searching for the highest number
max = 0
for i in list_a:
if i > str(max):
max = i
print(max)
my_max()
When i write numbers to input, sometimes the highest number is being printed, but not always.
For an example, if i write :"54,64,446 "
the number "64 is being printed. Do anybody knows why?
You need to map it into list of ints before you do the logic:
def my_max():
# using input to collect number to list
list_a = input("print your list with numbers: ").split(",")
# Searching for the highest number
return max(map(int, list_a))
print(my_max())
Sample run:
print your list with numbers: 54,64,446
446
Splitting on ',' gives you a list of strings. What you observed is an expected behaviour because you find max of a list of strings in contrast to list of integers.
Without using a max(), I would go something like this:
def my_max():
# using input to collect number to list
list_a = list(map(int, input("print your list with numbers: ").split(",")))
# Searching for the highest number
max = list_a[0]
for x in list_a[1:]:
if x > max:
max = x
return max
print(my_max())
Your list_a contains strings, not numbers. When you do your comparison, you are comparing the values of these strings. The result of this is the highest value alphabetically, rather than numerically.
Taken as strings rather than numbers, 64 > 54 > 446

Remove numbers from list which contains some particular numbers in python

Given List:
l = [1,32,523,336,13525]
I am having a number 23 as an output of some particular function.
Now,
I want to remove all the numbers from list which contains either 2 or 3 or both 2 and 3.
Output should be:[1]
I want to write some cool one liner code.
Please help!
My approach was :
1.) Convert list of int into list of string.
2.) then use for loop to check for either character 2 or character 3 like this:
A=[x for x in l if "2" not in x] (not sure for how to include 3 also in this line)
3.) Convert A list into integer list using :
B= [int(numeric_string) for numeric_string in A]
This process is quiet tedious as it involves conversion to string of the number 23 as well as all the numbers of list.I want to do in integer list straight away.
You could convert the numbers to sets of characters:
>>> values = [1, 32, 523, 336, 13525]
>>> number = 23
>>> [value for value in values
... if set(str(number)).isdisjoint(set(str(value)))]
[1]
You're looking for the filter function. Say you have a list of ints and you want the odd ones only:
def is_odd(val):
return val % 2 == 1
filter(is_odd, range(100))
or a list comprehension
[x for x in range(100) if x % 2 == 1]
The list comprehension in particular is perfectly Pythonic. All you need now is a function that returns a boolean for your particular needs.

Categories