Splitting list of elements without numpy array function [duplicate] - python

This question already has answers here:
How do I split a list into equally-sized chunks?
(66 answers)
Closed 1 year ago.
Example: I have a list:
[8, 3, 4, 1, 5, 9, 6, 7, 2]
And I need to make it look like this but without using numpy.array_split():
[[8, 3, 4], [1, 5, 9], [6, 7, 2]]
How can I do it? Not only for this one case, but when I have 4 elements, I want to have 2 and 2, (9 - 3,3,3 and 16 - 4,4,4,4) etc.

You can get the square root of the list's length then split it using a list comprehension. This will work for lists with the length of 4, 9, 16, ...:
lst = [8, 3, 4, 1, 5, 9, 6, 7, 2]
lst2 = [8, 3, 4, 1]
def split_equal(lst):
len_ = len(lst)
# returns emtpy list, if the list has no item.
if len_ == 0:
return []
n = int(len_ ** 0.5)
return [lst[i:i + n] for i in range(0, len_, n)]
output:
[[8, 3, 4], [1, 5, 9], [6, 7, 2]]
[[8, 3], [4, 1]]

You can use that:
def splitter(inlist):
n = len(inlist)
m = int(n ** 0.5)
if m*m != n:
raise Exception("")
return [[inlist[i+j] for j in range(m)] for i in range(m)]
print(splitter([8, 3, 4, 1]))
print(splitter([8, 3, 4, 1, 5, 9, 6, 7, 2]))
print(splitter([8, 3, 4, 1, 5, 9, 6, 7, 2, 8, 3, 4, 1, 5, 9, 6]))
Result:
[[8, 3], [3, 4]]
[[8, 3, 4], [3, 4, 1], [4, 1, 5]]
[[8, 3, 4, 1], [3, 4, 1, 5], [4, 1, 5, 9], [1, 5, 9, 6]]
Carefull, it will crash if the square of the len of input list is not integer.

def equal_array_split(arr, split_arr_len):
array_length = len(arr)
if array_length % split_arr_len == 0:
return [arr[i:i+split_arr_len] for i in range(0,array_length,split_arr_len)]
else:
return "Invalid split array length!!"
print(equal_array_split([1,2,3,4,5,6,7,8,9],3))
print(equal_array_split([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],4))
print(equal_array_split([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],8))
print(equal_array_split([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],2))
Output:
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]
[[1, 2, 3, 4, 5, 6, 7, 8], [9, 10, 11, 12, 13, 14, 15, 16]]
[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12], [13, 14], [15, 16]]

You can slice the list with a list comprehension. Assuming the input is a square number length:
import numpy as np
arr = [8, 3, 4, 1, 5, 9, 6, 7, 2]
n = int(np.sqrt(len(arr)))
result = [arr[i*n:(i+1)*n] for i in range(int(n))]

the split value being a square
list = [8, 3, 4, 1, 5, 9, 6, 7, 2]
result = []
N = split_value #split_value being the value required to split the list
for i in range(0,len(list),N):
result.append(list[i:i+N])
print(result)

Whitout numpy....
a = [8, 3, 4, 1, 5, 9, 6, 7, 2]
splitedSize = 3
a_splited = [a[x:x+splitedSize] for x in range(0, len(a), splitedSize)]
print(a_splited)

Related

Python: how to get random contiguous sets?

This is what I get by running train_test_split
In [1]:train_test_split([1,2,3,4,5,6,7,8,9,10],test_size = 0.2)
Out[1]: [[10, 3, 6, 5, 4, 2, 7, 9], [8, 1]]
However, what I want is a contiguous set, i.e.
[[1, 2, 3, 4, 5, 6, 7, 10], [8, 9]]
or
[[1, 2, 3, 4, 5, 8, 9, 10], [6, 7]]
or
[[1, 2, 5, 6, 7, 8, 9, 10], [3, 4]]
****** Please note that the following is also considered contiguous**
[[2, 3, 4, 5, 6, 7, 8, 9], [10, 1]]
How can I do this ?
Can you try the following:
import random
def custom_train_test_split(X, test_size=0.2):
temp = X.copy()
split_size = int(len(temp) * test_size)
start = random.randint(0, len(X) - split_size)
end = start + split_size
test = temp[start:end]
del temp[start:end]
return [temp, test]
X = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(custom_train_test_split(X, test_size=0.2))
print(custom_train_test_split(X, test_size=0.2))
print(custom_train_test_split(X, test_size=0.2))
Output:
[[1, 2, 5, 6, 7, 8, 9, 10], [3, 4]]
[[1, 2, 3, 4, 5, 8, 9, 10], [6, 7]]
[[3, 4, 5, 6, 7, 8, 9, 10], [1, 2]]

How to create a recursive separator?

I am trying to learn recursion and am separating odd and even values in two lists and merging them to another list as below:
Code:
def separateNumbers(L):
evenList = []
oddList = []
main = []
if len(L)==0:
return L
if L[0] % 2 == 0:
evenList.append(L[0])
separateNumbers(L[1:])
if L[0] % 2 == 1:
oddList.append(L[0])
separateNumbers(L[1:])
main.append(evenList)
main.append(oddList)
return main
inputList = [1,2,3,4,5,6,7,8,9,10]
L = separateNumbers(inputList)
print(L)
Input:
L = [1,2,3,4,5,6]
Output:
[[1,3,5], [2,4,6]]
The even and odd arrays reset everytime the recursive function is called, how can I fix this?
Tried with inner function:
def separateNumbers(L):
evenList = []
oddList = []
main = []
def inner(L):
if len(L)==0:
return L
if L[0] % 2 == 0:
evenList.append(L[0])
inner(L[1:])
if L[0] % 2 == 1:
oddList.append(L[0])
inner(L[1:])
main.append(evenList)
main.append(oddList)
return main
a = inner(L)
return a
Output:
[[2, 4, 6, 8, 10], [1, 3, 5, 7, 9], [2, 4, 6, 8, 10], [1, 3, 5, 7, 9], [2, 4, 6, 8, 10], [1, 3, 5, 7, 9], [2, 4, 6, 8,
10], [1, 3, 5, 7, 9], [2, 4, 6, 8, 10], [1, 3, 5, 7, 9], [2, 4, 6, 8, 10], [1, 3, 5, 7, 9], [2, 4, 6, 8, 10], [1, 3, 5, 7, 9], [2, 4, 6, 8, 10], [1, 3, 5, 7, 9], [2, 4, 6, 8, 10], [1, 3, 5, 7, 9], [2, 4, 6, 8, 10], [1, 3, 5, 7, 9]]
You don't need a nested function. try:
def separate_numbers(lst):
if not lst: # empty list
return [], []
odd, even = separate_numbers(lst[1:]) # recursion call
if lst[0] % 2: # if the first item is odd
return [lst[0], *odd], even
else: # if even
return odd, [lst[0], *even]
lst = [1,2,3,4,5,6,7,8,9,10]
print(separate_numbers(lst)) # ([1, 3, 5, 7, 9], [2, 4, 6, 8, 10])
The function calls itself using the tail part of the input list, receiving two lists: odd for odd numbers and even for even numbers. Then it returns those lists, after attaching the head element lst[0] to one of the lists.

Forming a magic square

We define a magic square to be an matrix of distinct positive integers from to where the sum of any row, column, or diagonal of length is always equal to the same number: the magic constant.
You will be given a matrix of integers in the inclusive range . We can convert any digit to any other digit in the range at cost of . Given , convert it into a magic square at minimal cost. Print this cost on a new line.
Note: The resulting magic square must contain distinct integers in the inclusive range .
For example, we start with the following matrix :
5 3 4
1 5 8
6 4 2
We can convert it to the following magic square:
8 3 4
1 5 9
6 7 2
This took three replacements at a cost of .
5-8 + 8-9 + 4-7 = 7
I Have Write a programm to slove this but i get the incorrect result when i try to run it.
def formingMagicSquare(s):
arr=[]
duplicates=[]
totaldifference=0
for i in range(0,len(s)):
linesum=sum(s[i])
for j in range(0,len(s[i])):
if(s[i][j] in arr and linesum!=15):
duplicates.append(i*10+j)
else:
arr.append(s[i][j])
for i in range(0,len(duplicates)):
iarr = duplicates[i]//10
jarr = duplicates[i]%10
linesum=sum(s[i])
difference=15-linesum
totaldifference = totaldifference + difference
return totaldifference
if __name__ == '__main__':
fptr = open(os.environ['OUTPUT_PATH'], 'w')
s = []
for _ in range(3):
s.append(list(map(int, input().rstrip().split())))
result = formingMagicSquare(s)
fptr.write(str(result) + '\n')
fptr.close()
class Magic(object):
pre = [
[[8, 1, 6], [3, 5, 7], [4, 9, 2]],
[[6, 1, 8], [7, 5, 3], [2, 9, 4]],
[[4, 9, 2], [3, 5, 7], [8, 1, 6]],
[[2, 9, 4], [7, 5, 3], [6, 1, 8]],
[[8, 3, 4], [1, 5, 9], [6, 7, 2]],
[[4, 3, 8], [9, 5, 1], [2, 7, 6]],
[[6, 7, 2], [1, 5, 9], [8, 3, 4]],
[[2, 7, 6], [9, 5, 1], [4, 3, 8]],
]
def evaluate(self, s):
totals = []
for p in self.pre:
total = 0
for p_row, s_row in zip(p, s):
for i, j in zip(p_row, s_row):
if not i == j:
total += max([i, j]) - min([i, j])
totals.append(total)
return min(totals)
def main():
s=[]
for _ in range(3):
s.append(list(map(int, input().rstrip().split())))
magic = Magic()
result = magic.evaluate(s)
print(result)
if __name__ == '__main__':
main()
Thank You I Have Write A new Code And I Have Change my code from the base.
I think you can easily try:
def forming_magic_square(s):
# Flaten s
s = list(itertools.chain.from_iterable(s))
magic_squares = [
[8, 1, 6, 3, 5, 7, 4, 9, 2],
[6, 1, 8, 7, 5, 3, 2, 9, 4],
[4, 9, 2, 3, 5, 7, 8, 1, 6],
[2, 9, 4, 7, 5, 3, 6, 1, 8],
[8, 3, 4, 1, 5, 9, 6, 7, 2],
[4, 3, 8, 9, 5, 1, 2, 7, 6],
[6, 7, 2, 1, 5, 9, 8, 3, 4],
[2, 7, 6, 9, 5, 1, 4, 3, 8],
]
costs = []
for magic_square in magic_squares:
costs.append(sum([abs(magic_square[i] - s[i]) for i in range(9)]))
return min(costs)

How to sum values from two iterator "lists"?

I have two iterators, which consists of a "list" that looks something like this:
[[1, 2, 3, 4, 5, 6],
[2, 4, 6, 8, 10, 12],
[3, 5, 8, 6, 1, 19],
[5, 9, 1, 9, 4, 6]]
Or, that is what it will look like if I just ran a for loop over them.
The reason for the iterator and not a list per se is due to memory. The true lists/arrays are way larger, this is just an example.
What I need to do is take one list and sum the columns of each index inside the list for all "outside" indices and then add them together for both lists like sum(list1) + sum(list2).
So basically:
list1: list2:
[[1, 2, 3, 4, 5, 6], [[5, 4, 3, 2, 1, 9],
[2, 4, 6, 8, 10, 12], [6, 3, 8, 1, 1, 6],
[3, 5, 8, 6, 1, 19], [1, 3, 2, 8, 2, 3],
[5, 9, 1, 9, 4, 6]] [5, 2, 9, 4, 2, 5]]
=> =>
[11, 20, 18, 20, 43] [17, 12, 22, 15, 23]
=>
[28, 32, 40, 35, 66]
So I iterate over the two lists, and for each list I need to sum the columns, and then in the end at the columns of the final two lists into one combined list.
I know how to do this if it were just regular lists, but since this is iterators/generators (don't know the correct term) I am really not sure how it is done.
You can use this to sum each one without loading everything into memory:
def sumIter(iter):
result = [0, 0, 0, 0, 0, 0] #Assuming there are always 6 items in each sub-list
for list in iter:
result = [(result[i] + list[i]) for i in range(6)]
And then:
sum1 = sumIter(iter1)
sum2 = sumIter(iter2)
result = [(sum1[i] + sum2[i]) for i in range(6)]
Using zip
Ex:
l1 = [
[1, 2, 3, 4, 5, 6],
[2, 4, 6, 8, 10, 12],
[3, 5, 8, 6, 1, 19],
[5, 9, 1, 9, 4, 6]
]
l2 = [
[5, 4, 3, 2, 1, 9],
[6, 3, 8, 1, 1, 6],
[1, 3, 2, 8, 2, 3],
[5, 2, 9, 4, 2, 5]
]
l1 = (sum(i) for i in zip(*l1))
l2 = (sum(i) for i in zip(*l2))
print( [sum(i) for i in zip(l1, l2)] )
Output:
[28, 32, 40, 42, 26, 66]
Using reduce since row can be added in numpy array.
reduce is an build-in function in python2
import numpy as np
from functools import reduce # only in python3
def sumup(one_row, another_row):
return one_row + another_row
test_list = np.array([[1, 2, 3, 4, 5, 6],
[2, 4, 6, 8, 10, 12],
[3, 5, 8, 6, 1, 19],
[5, 9, 1, 9, 4, 6]])
reduce(sumup, test_list)
Output
array([11, 20, 18, 27, 20, 43])
using numpy.sum
import numpy as np
l1 = np.sum([[1, 2, 3, 4, 5, 6], [2, 4, 6, 8, 10, 12], [3, 5, 8, 6, 1, 19], [5, 9, 1, 9, 4, 6]], axis=0)
l2 = np.sum([[5, 4, 3, 2, 1, 9],[6, 3, 8, 1, 1, 6], [1, 3, 2, 8, 2, 3],[5, 2, 9, 4, 2, 5]], axis=0)
print(l1 + l2)
Output
[28 32 40 42 26 66]

python generate sublist with offset and condition

Hey I'm trying to generate sublists of a list. For example I've a list like this:
l = [1,2,3,4,5,6,7,8,9,10,11,12]
I want to split them in sublists with the length of 4. But to first element is the same like the last element from the previous list AND like I said it must have the length of 4. Like this:
l1 = [1,2,3,4]
l2 = [4,5,6,7]
l3 = [7,8,9,10]
l4 = [10, 11, 12] <-- should be ignored
Does someone has an idea?! I'm thinking about an generator but I'm not quite sure.
A simple but flexible generator implementation:
def overlapping_sublists(l, n, overlap=1, start=0):
while start <= len(l) - n:
yield l[start:start+n]
start += n - overlap
Example usage:
>>> l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
>>> list(overlapping_sublists(l, 4))
[[1, 2, 3, 4], [4, 5, 6, 7], [7, 8, 9, 10]]
>>> list(overlapping_sublists(l, 4, 2, 3))
[[4, 5, 6, 7], [6, 7, 8, 9], [8, 9, 10, 11]]
a = []
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
for i in range(0, len(l)-3, 3):
a.append(l[i:i+4])
will give a = [[1, 2, 3, 4], [4, 5, 6, 7], [7, 8, 9, 10]]
or you can use as a list comprehension:
[l[i:i+4] for i in range(0, len(l)-3, 3)]
print([l[i:i+4] for i in range(0, len(l), 3)])
Output:
[[1, 2, 3, 4], [4, 5, 6, 7], [7, 8, 9, 10], [10, 11, 12]]
Only sublists of length 4:
print([m for m in [l[i:i+4] for i in range(0, len(l), 3)] if len(m) == 4])
Output:
[[1, 2, 3, 4], [4, 5, 6, 7], [7, 8, 9, 10]]
Using generators:
for n in (m for m in (l[i:i+4] for i in range(0, len(l), 3)) if len(m) == 4):
print(n)
Output:
[1, 2, 3, 4]
[4, 5, 6, 7]
[7, 8, 9, 10]

Categories