The problem is regarding reversing a list A of size N in groups of K. For example if A = [1,2,3,4,5], k = 3
Output = [3,2,1,5,4]
The error I get, when I run this is List Index out of range on line 4.
def reverseInGroups(A,N,K):
arr1 = []
for i in range(K):
arr1.append(A[(N-i)%K]) #line 4
for j in range(N-K):
arr1.append(A[N-j-1])
return arr1
This will implement what you are trying to achieve:
def reverseInGroups(A,K):
N = len(A)
arr1 = []
for i in range(0, N, K):
arr1.extend(A[i : i+K][::-1])
return arr1
print(reverseInGroups([1,2,3,4,5], 3))
Interestingly, the code in the question actually works in the example case, but it is not general. The case where it works is where N = 2*K - 1 (although where it does not work, the elements are in the wrong order rather than an IndexError).
Cant seem to reproduce your 'List index out of range' error, but your logic is faulty:
reverseInGroups(A,N,K):
arr1 = []
for i in range(K):
arr1.append(A[(N-i)%K]) #line 4
for j in range(N-K):
arr1.append(A[N-j-1])
return arr1
print(reverseInGroups([1,2,3,4,5],5, 3)) # works, others get wrong result
print(reverseInGroups([1,2,3,4,5,6],6, 3)) # wrong result: [1, 3, 2, 6, 5, 4]
prints:
[3, 2, 1, 5, 4] # correct
[1, 3, 2, 6, 5, 4] # wrong
You fix this and make this smaller by packing it into a list comprehension:
def revv(L,k):
return [w for i in (L[s:s+k][::-1] for s in range(0,len(L),k)) for w in i]
for gr in range(2,8):
print(gr, revv([1,2,3,4,5,6,7,8,9,10,11],gr))
to get:
2 [2, 1, 4, 3, 6, 5, 8, 7, 10, 9, 11]
3 [3, 2, 1, 6, 5, 4, 9, 8, 7, 11, 10]
4 [4, 3, 2, 1, 8, 7, 6, 5, 11, 10, 9]
5 [5, 4, 3, 2, 1, 10, 9, 8, 7, 6, 11]
6 [6, 5, 4, 3, 2, 1, 11, 10, 9, 8, 7]
7 [7, 6, 5, 4, 3, 2, 1, 11, 10, 9, 8]
You can also try with this:
def reverse(l, n):
result = []
for i in range(0, len(l)-1, n):
for item in reversed(l[i:i+n]):
result.append(item)
for item in reversed(l[i+n:]):
result.append(item)
return result
You can reverse the array upto index K and reverse the remaining part and add these both arrays.
def reverseInGroups(A,N,K):
return A[:K][::-1]+A[K:][::-1]
A = [1,2,3,4,5]
N = 5
K = 3
res = reverseInGroups(A,N,K)
print(res)
Related
Imagine we have the following list:
l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Now we want a random fraction of the previous list, i.e., a random sublist of length len(l) * frac. Therefore, if frac=0.2 the output list should have length 2 (0.2 x 10).
The following results are expected:
l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
l_new = sample(list=l, frac=0.3) # [4, 6, 8]
l_new = sample(list=l, frac=0.6) # [0, 1, 4, 6, 7, 8]
How can I achieve this behaviour? I have looked at random.sample, however it works by supplying a number of elements rather than a fraction of elements.
An alternative is to use random.sample with k = int(len(l) * frac), like so:
l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
frac = 0.3
l = random.sample(l, int(len(l) * frac))
print(l)
>>> [4, 7, 9]
Using it as a function:
# Randomly Sample a fraction of elements from a list
def random_sample(l, frac=0.5):
return random.sample(l, int(len(l) * frac))
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]
Essentially, I have to take a pre-existing list and a percentage and return a new list with the given percentage of items from the first list in a new list. I have what follows:
def select_stop_words(percent, list):
possible_stop_words = []
l = len(list)
new_words_list = l//(percent/100)
x = int(new_words_list - 1)
possible_stop_words = [:x]
return possible_stop_words
But this always yields the same results as the first. Help??
You might want to multiply l to percent / 100:
def select_stop_words(percent, lst):
return lst[:len(lst) * percent // 100]
lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(select_stop_words(50, lst)) # [1, 2, 3, 4, 5]
print(select_stop_words(20, lst)) # [1, 2]
print(select_stop_words(99, lst)) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(select_stop_words(100, lst)) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
arr=[1,2,3,4,5,6,7] # the array
n=2
j=0
while j<2:
temp1= arr[j]
j+=1
for i in range (n,len(arr)):
arr[i-n]=arr[i]
arr[len(arr)-1] = temp1
print (arr) #print
Blockquote
this is the output [3, 4, 5, 6, 7, 6, 2] but i need [3, 4, 5, 6, 7, 1, 2] can resolve my problem to re-edit my code
From your problem I understand that you want to split your array at position 2 and append it at the end.If my understanding is correct this code might help you, otherwise please elaborate your problem.
arr=[1,2,3,4,5,6,7] # the array
n=2
requires_arr=arr[n:]+arr[0:n]
print(requires_arr)
arr=[1,2,3,4,5,6,7] # the array
n=2
j=0
temp1 = []
while j<n:
temp1.append(arr[j])
j+=1
for i in range (n,len(arr)):
arr[i-n]=arr[i]
arr[-n:] = temp1
print (arr) #print
Based on the information you're providing, looks like you need to move the sublist(j, n) to the end of the original list. Being this the case, you can accomplish it by means of slicing:
arr = [1,2,3,4,5,6,7]
n = 2
j = 0
arr = arr[0:j] + arr[n:] + arr[j:n]
print(arr)
Result would be:
[3, 4, 5, 6, 7, 1, 2]
Another example:
arr = [1,2,3,4,5,6,7]
n = 3
j = 1
arr = arr[0:j] + arr[n:] + arr[j:n]
print(arr)
Results in:
[1, 4, 5, 6, 7, 2, 3]
This question already has answers here:
How do I split a list into equally-sized chunks?
(66 answers)
Closed 9 years ago.
def group(l,size):
length = len(l)
new = []
for i in range(0,length):
for j in range(i,size):
new[i].append(l[j])
print new
The above function group(list, size) that take a list and splits into smaller lists of given size.
I need something like this
input: group([1, 2, 3, 4, 5, 6, 7, 8, 9], 3)
output: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
But the problem with the above code is showing index out of range.what's wrong in code?
how to append elements into list of lists?
Use slice.
>>> def group(l, size):
... return [l[i:i+size] for i in range(0, len(l), size)]
...
>>> group([1, 2, 3, 4, 5, 6, 7, 8, 9], 3)
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
try:
def group(l,size):
length = len(l)
new = []
for i in range(0, length/size):
new.append([])
for i in range(0,len(new)):
for j in range(i*size,(i*size)+size):
new[i].append(l[i+j])
print new
edit:
no, don't do this. use slice like falsetru illustrates.
rough solution would be this :]
def group(l,size):
length = len(l)
newlist = []
newgroup = []
j = 0
for i in range(0,length):
if(j<size - 1):
j += 1
newgroup.append(l[i])
else:
j = 0
newgroup.append(l[i])
newlist.append(newgroup)
newgroup = []
if(newgroup != []):
newlist.append(newgroup)
return newlist
print(group([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], 3))
result: [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11]]