Multiply all combinations of two lists [closed] - python

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I really want to know how to extract all the element from two lists and multiply each other. For example, if there are two lists
A=[1,3,5,7,9]
B=[2,4,6,8]
I want to do 1X2, 1X4, 1X6, 1x8, 3x2... etc.
One element from A X one element from B.
I tried to use zip but because of length difference, I couldn't get right answers.

SInce your question seems to want the cartesian product between two lists, you can use itertools.product to bind every element from A with every element from B:
>>> from itertools import product
>>> A = [1,3,5,7,9]
>>> B = [2,4,6,8]
>>> list(product(A, B))
[(1, 2), (1, 4), (1, 6), (1, 8), (3, 2), (3, 4), (3, 6), (3, 8), (5, 2), (5, 4), (5, 6), (5, 8), (7, 2), (7, 4), (7, 6), (7, 8), (9, 2), (9, 4), (9, 6), (9, 8)]
Then if you want to multiply the the two elements in each tuple, you can do this:
>>> [x * y for x, y in product(A, B)]
[2, 4, 6, 8, 6, 12, 18, 24, 10, 20, 30, 40, 14, 28, 42, 56, 18, 36, 54, 72]

To get a random value from a list, you can do something similar to the following:
import random
lst = [10,20,30]
x = random.choice(lst)
Importing the random library gives you access to a ton of random generation tools. Per the random library documentation (https://docs.python.org/3/library/random.html), random.choice(seq) returns a random element from a non-empty sequence, such as a list. Thus, the code above randomly selects an element from lst and assigns that value to the variable x.
I don't want to give the solution away until you've tried using the random library, so I'll let you figure out how to use the information above.

You can use for loops:
Operation for each item in A with each item in B:
A=[1,3,5,7,9]
B=[2,4,6,8]
C = [] #Create an empty list
for i in A: #iter each element in A
for j in B: #iter each element in B
mult = i * j
C.append(mult) #Append the result in the list C
print(C)
Operation with a random item in A with each item in B:
import numpy as np
A=[1,3,5,7,9]
B=[2,4,6,8]
C = [] #Create an empty list
for i in A: #iter each element in A
i = np.random.randint(len(A)) #Chose a random number from A
for j in B: #iter each element in B
mult = A[i] * j #Multiply a random number from A with each element in B
C.append(mult) #Append the result in the list C
print(C)

Related

Efficiently check if elements lie between closed intervals [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 months ago.
Improve this question
I have a tuple x with elements as x = (2, 3, 4, 5). I also have another data structure that holds closed intervals with the number of elements equal to the number of elements in the tuple x, as y = ((2,3), (3.5, 4.5), (6, 9), (4, 7)).
Now, I can set up a nested loop and check if each element of x lies within the respective intervals in y. But the issue is that it takes too long for a tuple with 10000 elements. Although efficiency might not matter, I do want the code to run fast.
Note: By efficient I do mean time wise, where the code runs faster than any other 'obvious' solutions.
I was wondering if there was a more efficient way to do this using Python instead of the obvious nested loop? This seems to be only possible with the nested loops solution.
I don't have any code as I can not figure the question out. If I could have hints as to how to make it efficient then please provide them.
What about something like this
>>> x = (2, 3, 4, 5)
>>> y = ((2,3), (3.5, 4.5), (6, 9), (4, 7))
>>> def f(e):
... p, (q, r) = e
... return q <= p <= r
>>> list(map(f, zip(x,y)))
[True, False, False, True]
You can achieve this in linear time using one loop.
You only have to iterate once on both of the tuples, something like this:
x = (2, 3, 4, 5)
y = ((2,3), (3.5, 4.5), (6, 9), (4, 7))
for index, number in enumerate(x):
if number > y[index][1] or number < y[index][0]:
print(f'{number} is NOT in {y[index}')
else:
print(f'{number} is in {y[index]}')
the output is:
2 is in the interval (2, 3)
3 is NOT in the interval (3.5, 4.5)
4 is NOT in the interval (6, 9)
5 is in the interval (4, 7)
As i said, this solution will take O(n), instead of O(n^2)
Welcome to SO.
Although this is definitely not efficient for a small tuple, for a large one this will speed up the process greatly (from an O(n^2) solution to an O(n)). I hope this helps.
x = (2, 3, 4, 5)
y = ((2, 3), (3.5, 4.5), (6, 9), (4, 7))
for a, b in enumerate(y):
if b[0] <= x[a] <= b[1]:
print(f'{x[a]} is in between {b}.')
else:
print(f'{x[a]} is not in between {b}')
For boolean values:
interval = lambda t, i: [b[0] <= t[a] <= b[1] for a, b in enumerate(i)]
x = (2, 3, 4, 5)
y = ((2, 3), (3.5, 4.5), (6, 9), (4, 7))
print(interval(x, y))
All within linear (O(n)) time! Thanks for reading and have a great day.

How to remove tuple from the list?

everyone. I have a question about how to remove a Pythagorean triple from list in python.
The specific question ask me to create a list containing Pythagorean triples, but each triple can only occur once. My function is as following:
import numpy as np
def list_pythagorean_triples(amin,cmax):
x=list(range(amin,cmax))
y=[]
for a in x:
for b in x:
c=np.sqrt(a**2+b**2)
if c==int(c) and c<=cmax:
s=a,b,int(c)
y.append(s)
return y
U = list_pythagorean_triples(3,12)
U.sort()
print(U)
I got [(3, 4, 5), (4, 3, 5), (6, 8, 10), (8, 6, 10)] as the result. However, the expected one should be [(3, 4, 5), (6, 8, 10)].
Any idea to modify the code? Thank you very much!
You can use a set and order the values inside the tuples to avoid duplicates:
import numpy as np
def list_pythagorean_triples(amin,cmax):
x=list(range(amin,cmax))
y=set() # use a set
for a in x:
for b in x:
c=np.sqrt(a**2+b**2)
if c==int(c) and c<=cmax:
s= (min(a,b), max(a,b), int(c)) # order tuple content by size
y.add(s) # sets use add, not append
return list(y)
U = list_pythagorean_triples(3,12)
U.sort()
print(U)
Output:
[(3, 4, 5), (6, 8, 10)]
Couple of ways to solve this:
You can sort the tuple before appending and then deduplicate
def list_pythagorean_triples(amin,cmax):
x=range(amin,cmax)
y=[]
for a in x:
for b in x:
c=np.sqrt(a**2+b**2)
if c==int(c) and c<=cmax:
s=a,b,int(c)
y.append(sorted(s))
return sorted(set(y))
Or better still, you can only use values of b that are larger than a.
def list_pythagorean_triples(amin,cmax):
x=range(amin,cmax)
y=[]
for a in x:
for b in range(a,cmax):
c=np.sqrt(a**2+b**2)
if c==int(c) and c<=cmax:
s=a,b,int(c)
y.append(s)
return y

Python program to sort and count repeated no in list [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
Write a Python function histogram(l) that takes as input a list of integers with repetitions and returns a list of pairs as follows:
for each number n that appears in l, there should be exactly one pair (n,r) in the list returned by the function, where r is is the number of repetitions of n in l.
the final list should be sorted in ascending order by r, the number of repetitions. For numbers that occur with the same number of repetitions, arrange the pairs in ascending order of the value of the number.
For instance:
>>> histogram([13,12,11,13,14,13,7,7,13,14,12])
[(11, 1), (7, 2), (12, 2), (14, 2), (13, 4)]
>>> histogram([7,12,11,13,7,11,13,14,12])
[(14, 1), (7, 2), (11, 2), (12, 2), (13, 2)]
>>> histogram([13,7,12,7,11,13,14,13,7,11,13,14,12,14,14,7])
[(11, 2), (12, 2), (7, 4), (13, 4), (14, 4)]
The Counter object is perfect for this.
>>> from collections import Counter
>>> Counter([13,12,11,13,14,13,7,7,13,14,12])
Counter({13: 4, 12: 2, 14: 2, 7: 2, 11: 1})
Edit:
And if you want the result in a list of tuples sorted by value, you can do the following.
>>> count = Counter([13,12,11,13,14,13,7,7,13,14,12])
>>> sorted(count.items(), key=lambda c: c[1])
[(11, 1), (12, 2), (14, 2), (7, 2), (13, 4)]
Next time please share what you've tried yourself.
def make_histogram(lst):
new_lst = list(set([(i, lst.count(i)) for i in lst]))
new_lst.sort(key=lambda x: x[1])
return new_lst

What's the best way to create a list of tuples containing values taken from an array? [duplicate]

This question already has answers here:
How to get the cartesian product of multiple lists
(17 answers)
Closed 7 years ago.
I have three arrays/lists:
list1 = range(1,10)
list2 = range(1,10)
list3 = range(1,10)
I want to create an list of tuples containing an assortment of each of the values in my three lists. Essentially I want an output such as:
combo = [(1,1,1), (1,1,2), (1,1,3) ... (1,4,2), (1,4,3) ... (4,5,4), (4,5,5) ... (10,10,9), (10,10,10)]
It seems like such as simple problem, but I don't know where to start.
You can use itertools.product to generate the Cartesian product of lists:
>>> import itertools
>>> list(itertools.product(list1, list2, list3))
[(1, 1, 1),
(1, 1, 2),
(1, 1, 3),
(1, 1, 4),
(1, 1, 5),
(1, 1, 6),
(1, 1, 7),
(1, 1, 8),
(1, 1, 9),
(1, 2, 1),
(1, 2, 2),
(1, 2, 3)
...
itertools.product(list1, list2, list3) returns a generator object - only when you iterate over it will the tuples be returned. In the example code above, list is used to read the contents of the generator into a Python list.
Note that you can also use the repeat parameter of itertools which is much neater when your lists range over the same elements:
list(itertools.product(list1, repeat=3))
If I got it right, you want a Cartesian product of 3 lists? Well, there is a function for that in itertools
import itertools
result = list(itertools.product(list1, list2, list3))
You can also just create a list and append to it using nested loops. Just remember that if you also want the number 10, you need to change your range to range(1, 11) so that it stops at the number 11. It's like a < 11 (Doesn't include the number 11).
combo = []
for i in range(1, 11):
for j in range(1, 11):
for k in range(1, 11):
a = (i, j, k)
combo.append(a)
Use this :
combo=[]
for i in range(1,11):
for j in range(1,11):
for k in range(1,11):
combo.append( (i,j,k) )

How flatten a list of lists one step

I have a list of lists of tuples
A= [ [(1,2,3),(4,5,6)], [(7,8,9),(8,7,6),(5,4,3)],[(2,1,0),(1,3,5)] ]
The outer list can have any number of inner lists, the inner lists can have any number of tuples, a tuple always has 3 integers.
I want to generate all combination of tuples, one from each list:
[(1,2,3),(7,8,9),(2,1,0)]
[(1,2,3),(7,8,9),(1,3,5)]
[(1,2,3),(8,7,6),(2,1,0)]
...
[(4,5,6),(5,4,3),(1,3,5)]
A simple way to do it is to use a function similar to itertools.poduct()
but it must be called like this
itertools.product([(1,2,3),(4,5,6)], [(7,8,9),(8,7,6),(5,4,3)],[(2,1,0),(1,3,5)])
i.e the outer list is removed. And I don't know how to do that. Is there a better way to generate all combinations of tuples?
itertools.product(*A)
For more details check the python tutorial
This works for your example, if there is only one level of nested lists (no lists of lists of lists):
itertools.product(*A)
you can probably call itertools.product like so:
itertools.product(*A) # where A is your list of lists of tuples
This way it expands your list's elements into arguments for the function you are calling.
Late to the party but ...
I'm new to python and come from a lisp background. This is what I came up with (check out the var names for lulz):
def flatten(lst):
if lst:
car,*cdr=lst
if isinstance(car,(list)):
if cdr: return flatten(car) + flatten(cdr)
return flatten(car)
if cdr: return [car] + flatten(cdr)
return [car]
Seems to work. Test:
A = [ [(1,2,3),(4,5,6)], [(7,8,9),(8,7,6),(5,4,3)],[(2,1,0),(1,3,5)] ]
flatten(A)
Result:
[(1, 2, 3), (4, 5, 6), (7, 8, 9), (8, 7, 6), (5, 4, 3), (2, 1, 0), (1, 3, 5)]
Note: the line car,*cdr=lst only works in Python 3.0
This is not exactly one step, but this would do what you want if for some reason you don't want to use the itertools solution:
def crossprod(listoflists):
if len(listoflists) == 1:
return listoflists
else:
result = []
remaining_product = prod(listoflists[1:])
for outertupe in listoflists[0]:
for innercombo in remaining_product[0]:
newcombo = [outertupe]
newcombo.append(innercombo)
result.append(newcombo)
return result
def flatten(A)
answer = []
for i in A:
if type(i) == list:
ans.extend(i)
else:
ans.append(i)
return ans
This may also be achieved using list comprehension.
In [62]: A = [ [(1,2,3),(4,5,6)], [(7,8,9),(8,7,6),(5,4,3)],[(2,1,0),(1,3,5)] ]
In [63]: improved_list = [num for elem in A for num in elem]
In [64]: improved_list
Out[64]: [(1, 2, 3), (4, 5, 6), (7, 8, 9), (8, 7, 6), (5, 4, 3), (2, 1, 0), (1, 3, 5)]

Categories

Resources