Rotating list based on matching elements of a different list - python

Let's say I have two lists:
List1
[26, 45, 15]
List2
[13, 15, 20]
Assuming there is always exactly one element that is the same between the two lists, how would I reorder list2 into:
[20, 13, 15]
Where 15 becomes the third element of list2 because 15 is the third element of list1 (While the order of 13, 15, and then 20 is kept)? I have tried something like this:
# Reorder list2 to correspond with list1
key = 0
newOrder = []
for i in range(3):
for j in range(3):
if list2[i] == list1[j]: # if elements
key = i - j
for k in range(3):
index = k + key
if index == 3:
index = 0
if index == -1:
index = 2
newOrder.append(list2[index])
but it doesn't have a 100% success rate.

Assuming you want to rotate list2 so that the "shared" element is in the same position as in list1.
First, to get the matching indices you do not have to compare all elements. Instead, you can use a dict to store which element is at which position, and then get the matching position in a single pass over list2 (if the lists always have just 3 elements this does not matter, but for longer lists it reduces the complexity from O(n²) to O(n))
list1 = [26, 45, 15]
list2 = [13, 15, 20]
pos2 = {x: i for i, x in enumerate(list2)}
p1, p2 = next((i, pos2[x]) for i, x in enumerate(list1) if x in pos2)
Then, you can use a list comprehension to get the "rotated" elements from list2 using modulo % to "wrap around" when the index is larger than the length of the list.
n = len(list2)
res = [list2[(i+p2-p1) % n] for i in range(n)]
print(res) # [20, 13, 15]

This code gets the value and the index of the number in list1 that also exists in list2.
list1 = [26, 45, 15]
list2 = [13, 15, 20]
index, number = next((idx,number) for idx, number in enumerate(list1) if number in list2)
Then it removes the number from list2 and inserts it again at the wanted index:
list2.remove(number)
list2.insert(index,number)
print(list2)
Output will be
[13, 20, 15]

Related

Take the mean values of a number of integers in one list, based on the integers in another list

I have one list containing a large number of integers, and then another list also containing integers that (if added together) sums up to the total amount of integers in the first list. I wish to create a function which iterates over the second list, and for each number in the second list, takes the mean of the values in the first list and repeats for all integers in the second list...making one final third list containing the desired mean-values.
For example: A small portion of my two lists look like this: [20, 15, 20, 30, 40, 20, 10, 8], [2, 3, 1, 2]
So since 2 is the first number in my second list, I want to take the mean of the first two integers in my first list, and then the 3 next, and so on, and add these into a third list.
Here is a brief idea of what I am thinking, but its obviously not complete.
def mean_values(list_of_numbers, numbers_for_meanvalue):
list_of_means = []
for i in numbers_for_meanvalue:
mean = sum(list_of_numbers[0]+...+list_of_numbers[i])/numbers_for_meanvalue[i]
list_of_means.append[mean]
return list_of_means
you can take a slice of a list: list[start : end].
def mean_values(list_of_numbers, numbers_for_meanvalue):
list_of_means = []
last_start = 0
for num in numbers_for_meanvalue:
mean = sum(list_of_numbers[last_start:last_start + num]) / len(list_of_numbers[last_start:last_start + num])
last_start += num
list_of_means.append[mean]
return list_of_means
I don't if I understand you correctly, but:
>>> a = [20, 15, 20, 30, 40, 20, 10, 8]
>>> b = [2, 3, 1, 2]
>>> n = 0
>>> for e in b:
... sl = a[n:n+e]
... print(sl,(sum(sl) / e))
... n += e
...
[20, 15] 17.5
[20, 30, 40] 30.0
[20] 20.0
[10, 8] 9.0

Python produce alternative numbers list from a list of n numbers

I have a list of n numbers. I want to group them in g groups. Also, I want to reverse elements in every odd group. Finally, I would combine all elements in even and odd groups into a new sublist. First I am giving what answer I am expecting and where I went wrong:
Expected answer:
num = 14
grp = 4
# A list of num natural numbers arranged in group (row) of 4 numbers
lst =
[0,1,2,3,
4,5,6,7,
8,9,10,11,
12,13]
lst =
[[0,1,2,3],
[4,5,6,7],
[8,9,10,11],
[12,13]]
# Reverse elements in odd rows
newlst =
[[0,1,2,3],
[7,6,5,4], # reversed here
[8,9,10,11],
[13,12]] # reversed here
# combine elements in all sublists by their position
# combine first element in all sublists into a new sublist
sollst =
[[0,7,8,13],[1,6,9,12],[2,5,10],[3,4,11]]
My solution:
num = 14
grp = 4
#### print
lst= list(range(0,num,1))
newlst= [lst[i:i+grp:1] for i in range(0,num,grp)]
evnlst = newlst[0::2]
oddlst = newlst[1::2]
newoddlst = [oddlst [i][::-1] for i in range(len(oddlst))]
sollst= evnlst + newoddlst
# This gives [[0, 1, 2, 3], [8, 9, 10, 11], [7, 6, 5, 4], [13, 12]]
from itertools import zip_longest
print([[x for x in t if x is not None] for t in zip_longest(fevngps)])
Present answer:
I reached the one step before the final answer and now I have to combine the lists of different lengths and I am running into an error
TypeError: 'int' object is not subscriptable
One approach:
from itertools import zip_longest
num = 14
grp = 4
lst = list(range(0, num, 1))
newlst = [lst[i:i + grp:1] for i in range(0, num, grp)]
# build new list where the sub-list are reversed if in odd indices
revlst = [lst[::-1] if i % 2 == 1 else lst for i, lst in enumerate(newlst)]
# zip using zip_longest and filter out the None values (the default fill value of zip_longest)
result = [[v for v in vs if v is not None] for vs in zip_longest(*revlst)]
print(result)
Output
[[0, 7, 8, 13], [1, 6, 9, 12], [2, 5, 10], [3, 4, 11]]

Change value of index in a for loop python

AN implementation of Crohn(Крона) algorithm used in Scheduling theory, is it possible to change the data of the current index in a for loop in python?
I have a code like so;
link to the full code
#list1 is a 2d array
list1 = [[12, 3, 17], [14], [10, 12, 15]]
cond = 1
while cond:
d = delta(sum_calc(list1))
#delta() finds the difference between the list with the highest sum
#and the list with the minimum sum, then returns the
#difference(d[0]), index_of_list_with_max_sum(d[1]), #index_of_list_with_min_sum(d[2])
#d = [23, 2, 1]
if cond == 0:
break
else:
for i in list1[d[1]]:
if d[0] > i:
move(list1[d[1]], list1[d[2]])
#move() moves the min element from list1, to list2
else:
cond = 0
what I am trying to do is, given an index, loop through the elements of that list, then check if num is greater than i (element), after that we do some operations, like moving the smallest element from the current list we are looping from, to another list. then we have some operations, after that I want to change the value of i, to something like
#the index might change
i = l[index]
the problem I am facing is that when I do that, it continues looping from the first index.
Is there a way I can reset it, so that it starts looping from other elements?
I HAVE USED A WHILE LOOP, because I want the procedure to repeat itself and until d[0] !> i:
#since the list with the highest sum is list1[2], we got 2 from d,
#next step is to loop through the elements in that list and check if
#there's an element which is less than d[0](the difference between max and min sum)
#expected results
#after first iteration
list1 = [[12, 3, 17], [14, 10], [12, 15]]
d = [8, 0, 1]
#after second iteration
list1 = [[12, 17], [14, 10, 3], [12, 15]]
d = [2, 0, 1]
#the problem is it stops here, I want it to calculate delta again then #repeat the process, but after debugging, i found that in the second #iteration i = 15, which the second element of the list, but it should #be like that.
Try to combine while loop with index ?
example:
lst = [1,2,3]
idx = 0
while idx < len(lst):
print(lst[idx])
idx += 1
if idx == len(lst):
# Reset index
idx = 0
EDIT
After debugging I found your errors - You havent been assigning the new delta result to d where you have been referencing from your code thus you never got the new indexes
cond = True
idx = 0
while cond and idx < len(l[d[1]]):
if d[0] > l[d[1]][idx]:
move(l[d[1]], l[d[2]])
s = sum_calc(l)
d = delta(s)
print("l =", l)
print("s =", s)
print("d =", d)
print("")
idx = 0
else:
cond = False
idx += 1
Output:
l = [[12, 3, 17], [14, 10], [12, 15]]
s = [32, 24, 27]
d = [8, 0, 1]
l = [[12, 17], [14, 10, 3], [12, 15]]
s = [29, 27, 27]
d = [2, 0, 1]

Compare elements of two list

I have been given two lists, say list1 and list2. I have to arrange the elements of the list1 in such a way that at particular index the element of list1 is greater than the element of list2. We have to find how many such elements of list1 are there.
For example:
list1=[20,30,50]
list2=[60,40,25]
Here only element index 2 is greater i.e. 50>25, but if we swap 50 and 30 in list1
So,
list1=[20,50,30]
list2=[60,40,25]
then 50 > 40 ( at index 1) and 30 > 25 (at index 2). So we got 2 elements 50 and 30 which are greater at their respective index.
Here is my approach
def swap(a,b):
a,b=b,a
return a,b
n=3
g=list(map(int,input().split()))
o=list(map(int,input().split()))
c=0
for i in range(n):
if o[i]>g[i]:
for j in range(i+1,n):
if g[j]>o[i]:
g[i],g[j]=swap(g[i],g[j])
c+=1
break
else:
c+=1
print(c)
But for
list1= [3,6,7,5,3,5,6,2,9,1]
list2= [2,7,0,9,3,6,0,6,2,6]
Its giving c=6 but expected output is c=7
You have to sort the two lists and then run through them to find "matches" where a value of list1 is greater than the next value of list2. This will pair up the values with the smallest possible difference and thus maximize the pairings.
For example:
list1=[20,30,50]
list2=[60,40,25]
iter1 = iter(sorted(list1)) # iterator to run through sorted list1
n1 = next(iter1,None) # n1 is current number in list1
count = 0 # count of paired elements (n1>n2)
for n2 in sorted(list2): # go through sorted list 2
while n1 is not None and n1 <= n2: # skip over ineligible items of list1
n1 = next(iter1,None)
if n1 is None: break # stop when list 1 is exhausted
count += 1 # count 1 pair and move on to next of list2
print(count) # 2
list1= [3,6,7,5,3,5,6,2,9,1]
list2= [2,7,0,9,3,6,0,6,2,6]
list1 = sorted(list1)
it = iter(enumerate(list1))
list2 = sorted(list2)
c = next(it)
good = []
for i, n in enumerate(list2 ):
try:
while c[1] < n:
c = next(it)
good.append([i, c[0]])
c = next(it)
except StopIteration:
break
for idx1, idx2 in good:
list1[idx1], list1[idx2] = list1[idx2], list1[idx1]
final_l1_l2 = sum(a > b for a, b in zip(list1, list2))# how many l1 are > l2
print(final_l1_l2)
output:
7
also, you can print list1 and list2 after the rearrange:
print(list1)
print(list2)
output:
[1, 2, 3, 3, 5, 6, 6, 7, 9, 5]
[0, 0, 2, 2, 3, 6, 6, 6, 7, 9]
the idea is to sort both lists and then to check what elements from list1 are greater than the elements from list2 if one element from list1 it is smaller then the current element from list2 just go to the next element from the list1 till there are no more elements in list1

How do I multiply a list of elements with another list of lists in Python

I have two list with arbitrary numbers: list_1 = [2,4] and list_2 = [[10,20,30], [100,1000,10000]] i need the first index of list_1(i.e list_1[0]) to multiply with each number in list_2[0](i.e the sub_list). the same should happen with the next index such as in a for loop.
so far i have tried
list_1 = [2,4]
list_2 = [[10,20,30], [100,1000,10000]]
for i in list_1:
for j in list_2:
print(i * j)
The code either duplicates the list or throws an error at me. any help is much appreciated.
If I'm reading you correctly, for your example, you want list_1[0] to be multiplied by each element of list_2[0], and list_1[1] to be multiplied by each element of list_2[1]. The correct way to do this is to zip list_1 and list_2 together (to get the multiplier and the associated sublist as pairs), then have an inner loop over the sublist:
for op1, sublist in zip(list_1, list_2):
for op2 in sublist:
print(op1 * op2)
Your code failed, because you were (effectively) trying to multiply op1 by each sublist, not the contents of one sublist, so you invoked sequence multiplication, performing 2 * [10, 20, 30] to get [10, 20, 30, 10, 20, 30], and 2 * [100, 1000, 10000] to get [100, 1000, 10000, 100, 1000, 10000], rather than multiplying 2 by 10, 20 and 30 individually as intended.
list_1 = [2,4]
list_2 = [[10,20,30], [100,1000,10000]]
for i in range(len(list_1)):
... for item in list_2:
... for j in range(len(item)):
... print(list_1[i]*item[j])
Returns
20
40
60
200
2000
20000
40
80
120
400
4000
40000

Categories