Python array logic - python

I am trying to create a list of lists with the input of m and n, where m is the number of lists within the main list and n is the number of elements within each given list. The grid should contain the integers from start to start + rows * cols - 1 and be ascending. But, every odd numbered row should be descending instead.
The code I've written is returning the expected results, but my automated tester is saying it's incorrect. Maybe my logic is messed up somewhere?
inputs:
start = 1, m = 3, n = 5
expected:
[[1,2,3,4,5],[10,9,8,7,6],[11,12,13,14,15]]
result = []
mylist = []
start = 1
for x in range(0, rows):
for x in range(0, cols):
result.append(start)
start += 1
for y in range(0, rows):
if y%2 != 0:
mylist.append(result[cols - 1::-1])
del result[cols - 1::-1]
else:
mylist.append(result[0:cols])
del result[0:cols]
return mylist

One possible solution, using itertools.count:
from itertools import count
def build(m, n, start=1):
lst, c = [], count(start)
for i in range(m):
lst.append([next(c) for j in range(n)][::-1] if i % 2 else [next(c) for j in range(n)])
return lst
print(build(3, 5, 1))
Prints:
[[1, 2, 3, 4, 5], [10, 9, 8, 7, 6], [11, 12, 13, 14, 15]]
print(build(3, 0, 1))
Prints:
[[], [], []]

just generate the list of numbers you need which will be n * m, in your case that would generate 0 to 14 in the python range function. However as we want to start at ` then we need to add the start offset too the range end.
Now we can generate all the numbers we need we just need to think about how to create them.
well we can add numbers to the list until the list reaches the size of n, then we need to start a new list, However if the list we just finished is an even numbered row then we need to reverse that list.
def build_lists(m, n, start=1):
data =[[]]
for i in range(start, n * m + start):
if len(data[-1]) < n:
data[-1].append(i)
else:
if len(data) % 2 == 0:
data[-1] = data[-1][::-1]
data.append([i])
if len(data) % 2 == 0:
data[-1] = data[-1][::-1]
return data
print(build_lists(3, 5))
print(build_lists(6, 3))
print(build_lists(6, 2, 100))
OUTPUT
[[1, 2, 3, 4, 5], [10, 9, 8, 7, 6], [11, 12, 13, 14, 15]]
[[1, 2, 3], [6, 5, 4], [7, 8, 9], [12, 11, 10], [13, 14, 15], [18, 17, 16]]
[[100, 101], [103, 102], [104, 105], [107, 106], [108, 109], [111, 110]]

Related

How can I transform a list in a list of lists if I need to skip some characters in between?

Let lst = [13, 1, 14, -64, 9, -64, 14, 5]
How can I create a list of lists without taking into account the negative number ?
Result would be [[13,1,14], [9], [14,5]]
lst = [13, 1, 14, -64, 9, -64, 14, 5]
lst_index = []
for i,v in enumerate(lst):
if lst[i] == -64:
lst_index.append(i)
So this is what I have done to retrieve the index of each negative number. Now I should remove it from the list and create list of lists but how?? Thank you !
Using itertools.groupby:
from itertools import groupby
lst = [13, 1, 14, -64, 9, -64, 14, 5]
res = [list(group) for key, group in groupby(lst, lambda x : x > 0) if key]
print(res)
Output
[[13, 1, 14], [9], [14, 5]]
Or simply:
current, res = [], []
for e in lst:
if e < 0:
if current:
res.append(current)
current = []
else:
current.append(e)
if current:
res.append(current)
print(res)
Output
[[13, 1, 14], [9], [14, 5]]
You could do something like this:
def group_positives(lst):
result = []
temp = []
for value in lst:
if value > 0:
temp.append(value)
else:
if temp:
result.append(temp)
temp = []
# Also append last temp if not empty
if temp:
result.append(temp)
return result
One solution: every time you find a negative number add to the new list an empty list, and after that append the positive numbers to the last element of the new list, see below.
lst = [13, 1, 14, -64, 9, -64, 14, 5]
new_lst = []
start_lst = True
for v in lst :
if v < 0:
start_lst = True
else:
if start_lst == True :
start_lst = False
new_lst.append([])
new_lst[-1].append(v)
print(new_lst)
What I do here is just adding The numbers to a New list till I find a negative number if a Negative number met The else Condition
1-Stop
2-Add the List you have to COMBO
3-Jump over this number by index+1
the last iteration will not add the last list because there is no negative number to Stop and do the 3 steps so I added -1 at the end to go to else
Summary
Add Numbers to the list till you find a negative number then add this list to combo
in the end, you will have the list but you will not add it combo as you didn't face a negative number ( so I added -1 )
lst = [13, 1, 14, -64, 9, -64, 14, 5]
def Test(V):
V.append(-1)
new = []
Combo = []
for index, value in enumerate(V):
if(lst[index] > 0):
new.append(lst[index])
else:
index += 1
Combo.append(new)
new = list()
return Combo
z = Test(lst)
print(z)
Output
[[13, 1, 14], [9], [14, 5]]

how to create a multidimensional array on the fly using python?

I have a loop which generates a value_list each time it runs, at the end of each iteration i want to append all the lists into a one multi dimensional array
I have:
value_list = [1,2,3,4] in 1st iteration
value_list = [5,6,7,8] in 2nd iteration
value list = [9,10,11,12] in 3rd iteration
etc...
At the end of each iteration I want one multi dimensional array like
value_list_copy = [[1,2,3,4]] in the 1st iteration
value_list_copy = [[1,2,3,4],[5,6,7,8]] in the 2nd iteration
value_list_copy = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
etc...
How could I achieve this?
Thanks
You can use a nested comprehension and itertools.count:
from itertools import count, islice
cols = 4
rows = 5
c = count(1)
matrix = [[next(c) for _ in range(cols)] for _ in range(rows)]
# [[1, 2, 3, 4],
# [5, 6, 7, 8],
# [9, 10, 11, 12],
# [13, 14, 15, 16],
# [17, 18, 19, 20]]
The cool kids might also want to zip the count iterator with itself:
list(islice(zip(*[c]*cols), rows))
# [(1, 2, 3, 4),
# (5, 6, 7, 8),
# (9, 10, 11, 12),
# (13, 14, 15, 16),
# (17, 18, 19, 20)]
If you are using Python3.8 then use Walrus assignment(:=).
For Syntax and semantic.
count=0
rows=5
cols=4
[[(count:=count+1) for _ in range(cols)] for _ in range(rows)]
Output:
[[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16],
[17, 18, 19, 20]]
Without using :=.
rows=5
cols=4
[list(range(i,i+cols)) for i in range(1,rows*cols,cols)]
Try this:
limit = 10
length_of_elements_in_each_list = 4
[range(i, i+length_of_elements_in_each_list) for i in range(1, limit)]
You can set a limit and length_of_elements_in_each_list according to your need.
Try this below :
value_list_copy = []
for i in range(n): # ----------> Assuming n is the number of times your loop is running
value_list_copy.append(value_list) # ------ Append your value list in value_list_copy in every iteration
Here you will get an array of arrays.
print(value_list_copy)
Here are two other possible solutions:
Double for loop approach
rows, cols, start = 3, 4, 1
value_list_copy = []
for j in range(rows):
value_list = []
for i in range(start, cols + start):
value_list.append((j*cols)+i)
value_list_copy.append(value_list)
print(
f'value_list = {value_list}\n'
f'value_list_copy = {value_list_copy}\n'
)
List comp method
rows, cols, start = 3, 4, 1
value_list_copy_2 = [
[
(j*cols)+i for i in range(start, cols + start)
] for j in range(rows)
]
print(f'value_list_copy_2 = {value_list_copy_2}')
Python Tutor Link to example code

How to get the values in the dictionary into the list form and then square them into list

I have a dictionary of values in tuple form, how to get the values in list form.
I want to get values from the tuples and create new lists and create another 3 lists with squares from them.
dictionary={1:(1,2,3),2:(3,4,5),3:(6,7,8),4:(9,10,11),5:(12,13,14)}
s=list(d.values())
d=[item for t in s for item in t]
print(d)
I used list comprehension i got this output:
[1, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
Using list comprehension
Expected_output:
[1,3,6,9,12],
[2,4,7,10,13],
[3,5,8,11,14],
squares**2 output above three list :
[1,9,36,81,144],
[4,16,49,100,169],
[9,25,64,121,196]
Provided with a Dictionary
First take a empty list and assign it to a variable “l”
Using list comprehension separate the values and store that in a variable
Iterate the values and append the empty list “l”
Now iterate the “l” using index values i[o], i[1], i[2] and store in various variables respectively
Using map function square the variables and store the values and print them using the list of variables
x = {
1:(1,2,3),
2:(4,5,6),
3:(7,8,9),
4:(10,11,12),
5:(13,14,15)
}
l = []
y = [i for i in x.values()]
for i in y:
l.append(i)
print(l)
m = [i[0] for i in l]
n = [i[1] for i in l]
o = [i[2] for i in l]
m1 = map(lambda i:i**2, m)
n1 = map(lambda i:i**2, n)
o1 = map(lambda i:i**2, o)
print(m)
print(list(m1))
print(n)
print(list(n1))
print(o)
print(list(o1))
you can use zip to collect the index elements of each list together, then use list comprehension to square them
dictionary={1:(1,2,3),2:(3,4,5),3:(6,7,8),4:(9,10,11),5:(12,13,14)}
list_vals = list(zip(*dictionary.values()))
squares = [[num ** 2 for num in nums] for nums in list_vals]
print(list_vals)
print(squares)
OUTPUT
[(1, 3, 6, 9, 12), (2, 4, 7, 10, 13), (3, 5, 8, 11, 14)]
[[1, 9, 36, 81, 144], [4, 16, 49, 100, 169], [9, 25, 64, 121, 196]]
Thanks to comments from #roganjosh highlighting that the dict will only be assured to be ordered if the pythong version is 3.6 or higher. If your python version is less than that you would first need to sort the values by order of the keys. Below is an example.
dictionary={2:(3,4,5),3:(6,7,8),4:(9,10,11),5:(12,13,14),1:(1,2,3)}
ordered_key_val = sorted(dictionary.items(), key=lambda items: items[0])
list_vals = list(zip(*[val for key, val in ordered_key_val]))
squares = [[num ** 2 for num in nums] for nums in list_vals]
print(list_vals)
print(squares)
You can use numpy to transpose the entire list once the values of the dictionary are obtained. You can use the below program
import numpy as np
dictionary={1:(1,2,3),2:(3,4,5),3:(6,7,8),4:(9,10,11),5:(12,13,14)}
list_out= []
for i in dictionary.keys():
list_out.append(dictionary[i])
tran_list = np.transpose(list_out)
out_list = tran_list*tran_list
Output of this is:
>>> out_list
array([[ 1, 9, 36, 81, 144],
[ 4, 16, 49, 100, 169],
[ 9, 25, 64, 121, 196]])
This is an array output! Anyway if you want it only in the list, ofcourse , you can play with it!
You can do this way:
>>> temp = list(zip(*dictionary.values()))
>>> [list(i) for i in temp]
[[1, 3, 6, 9, 12], [2, 4, 7, 10, 13], [3, 5, 8, 11, 14]]
>>> [[i**2 for i in elem] for elem in temp]
[[1, 9, 36, 81, 144], [4, 16, 49, 100, 169], [9, 25, 64, 121, 196]]
I have one dictionary here
d={1:(1,2,3),2:(4,5,6),3:(7,8,9),4:(10,11,12),5:(13,14,15)}
first I want to get values in tuple in three lists then I used list comprehension here The below code gives the tuple values in three lists
myList1 = [d [i][0] for i in (d.keys()) ]
print(myList1)
myList2 = [d [i][1] for i in (d.keys()) ]
print(myList2)
myList3 = [d [i][2] for i in (d.keys()) ]
print(myList3)
Here all the tuple values converted into list form
[1, 4, 7, 10, 13]
[2, 5, 8, 11, 14]
[3, 6, 9, 12, 15]
Now I want to squares the elements in three lists here I Used lambda expression the below code squares the elements in the lists
a1= list(map(lambda x: x**2 ,myList1))
print(a1)
a2= list(map(lambda x: x**2 ,myList2))
print(a2)
a3= list(map(lambda x: x**2 ,myList3))
print(a3)
The output is:
[1, 16, 49, 100, 169]
[4, 25, 64, 121, 196]
[9, 36, 81, 144, 225]

Python: function to group number by tens place

Takes a list of numbers and groups the numbers by their tens place, giving every tens place it's own sublist.
ex:
$ group_by_10s([1, 10, 15, 20])
[[1], [10, 15], [20]]
$ group_by_10s([8, 12, 3, 17, 19, 24, 35, 50])
[[3, 8], [12, 17, 19], [24], [35], [], [50]]
my approach:
limiting = 10
ex_limiting = 0
result = []
for num in lst:
row = []
for num in lst:
if num >= ex_limiting and num <= limiting:
row.append(num)
lst.remove(num)
result.append(row)
ex_limiting = limiting
limiting += 10
But it returns [[1], [10, 20]].
What's wrong with my approach and how can I fix it?
You may already have a correct answer, but here's an alternative solution:
def group_by_10s(mylist):
result = []
decade = -1
for i in sorted(mylist):
while i // 10 != decade:
result.append([])
decade += 1
result[-1].append(i)
return result
group_by_10s([8, 12, 3, 17, 19, 24, 35, 50])
#[[3, 8], [12, 17, 19], [24], [35], [], [50]]
It uses only plain Python, no extra modules.
You can use a list comprehension:
def group_by_10s(_d):
d = sorted(_d)
return [[c for c in d if c//10 == i] for i in range(min(_d)//10, (max(_d)//10)+1)]
print(group_by_10s([1, 10, 15, 20]))
print(group_by_10s([8, 12, 3, 17, 19, 24, 35, 50]))
print(group_by_10s(list(range(20))))
Output:
[[1], [10, 15], [20]]
[[3, 8], [12, 17, 19], [24], [35], [], [50]]
[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]]
Credit to advice for not iterating list during loop.
I got this answer at the end, for anyone who wants the answer.
Thanks for support!
def group_by_10s(numbers):
external_loop = int(max(numbers)/10)
limiting = 10
ex_limiting = 0
result = []
for external_loop_count in range(external_loop+1):
row = []
for num in numbers:
if num >= ex_limiting and num < limiting:
row.append(num)
row.sort()
result.append(row)
ex_limiting = limiting
limiting += 10
return(result)
How about this one?
numbers = [8, 12, 3, 17, 19, 24, 35, 50]
def group_by_10s(numbers):
arr = []
for i in range((max(numbers) / 10) + 1):
arr.append([])
numbers.sort()
for number in numbers:
if number < 10:
arr[0].append(number)
else:
index = number / 10
arr[index].append(number)
return arr
print group_by_10s(numbers)
# [[3, 8], [12, 17, 19], [24], [35], [], [50]]
Do not modify the list while you are iterating over it, as when you remove items from it, some items get skipped over. Also change the bounds so that you will only append to row if num < limiting. I would add in a check to make sure the list has elements before adding it to result:
for num in lst:
row = []
for num in lst:
if num >= ex_limiting and num < limiting:
row.append(num)
if len(row) > 0 :
result.append(row)
ex_limiting = limiting
limiting += 10
This will yield:
[[1], [10, 15], [20]]

Python list slicing

I'm not able understand what to do here. Can someone help.
I've a few lists:
array = [7,8,2,3,4,10,5,6,7,10,8,9,10,4,5,12,13,14,1,2,15,16,17]
slice = [2, 4, 6, 8, 10, 12, 15, 17, 20, 22]
intervals = [12, 17, 22]
output = []
intermediate = []
slice is a list of indices I need to get from slicing array. interval is a list of indices used to stop the slicing when slice[i] is interval[j] where i and j are looping variables.
I need to form a list of lists from array based on slice and intervals based on the condition that when slice[i] is not interval[j]
intermediate =intermediate + array[slice[i]:slice[i+1]+1]
here in my case:
when slice[i] and interval[j] are equal for value 12. So I need to form a list of lists from array
intermediate = array[slice[0]:slice[0+1]+1] + array[slice[2]:slice[2+1]+1] + array[slice[4]:slice[4+1]+1]
which is
intermediate = array[2:(4+1)] + array[6:(8+1)] + array[10:(12+1)]
and when slice[i] is interval[j] output = output + intermediate and the slicing is continued.
output = output + [intermediate]
which is
output = output + [array[2:(4+1)] + array[6:(8+1)] + array[10:(12+1)]]
now the next value in interval is 17 so till we have 17 in slice we form another list from array[slice[6]:slice[6+1]+1] and add this to the output. This continues.
The final output should be:
output = [array[slice[0]:slice[0+1]+1] + array[slice[2]:slice[2+1]+1] + array[slice[4]:slice[4+1]+1] , array[slice[6]:slice[6+1]+1], array[slice[8]:slice[8+1]+1]]
which is
output = [[2, 3, 4, 5, 6, 7, 8, 9, 10], [12, 13, 14], [15, 16, 17]]
A straightforward solution:
array_ = [7,8,2,3,4,10,5,6,7,10,8,9,10,4,5,12,13,14,1,2,15,16,17]
slice_ = [2, 4, 6, 8, 10, 12, 15, 17, 20, 22]
intervals = [12, 17, 22]
output = []
intermediate = []
for i in range(0, len(slice_), 2):
intermediate.extend(array_[slice_[i]:slice_[i+1]+1])
if slice_[i+1] in intervals:
output.append(intermediate)
intermediate = []
print output
# [[2, 3, 4, 5, 6, 7, 8, 9, 10], [12, 13, 14], [15, 16, 17]]
I have changed some variable names to avoid conflicts.
On large data, you may convert intervals to a set.
Here is a recursive solution which goes through the index once and dynamically check if the index is within the intervals and append the sliced results to a list accordingly:
def slicing(array, index, stops, sliced):
# if the length of index is smaller than two, stop
if len(index) < 2:
return
# if the first element of the index in the intervals, create a new list in the result
# accordingly and move one index forward
elif index[0] in stops:
if len(index) >= 3:
sliced += [[]]
slicing(array, index[1:], stops, sliced)
# if the second element of the index is in the intervals, append the slice to the last
# element of the list, create a new sublist and move two indexes forward accordingly
elif index[1] in stops:
sliced[-1] += array[index[0]:(index[1]+1)]
if len(index) >= 4:
sliced += [[]]
slicing(array, index[2:], stops, sliced)
# append the new slice to the last element of the result list and move two index
# forward if none of the above conditions satisfied:
else:
sliced[-1] += array[index[0]:(index[1]+1)]
slicing(array, index[2:], stops, sliced)
sliced = [[]]
slicing(array, slice_, intervals, sliced)
sliced
# [[2, 3, 4, 5, 6, 7, 8, 9, 10], [12, 13, 14], [15, 16, 17]]
Data:
array = [7,8,2,3,4,10,5,6,7,10,8,9,10,4,5,12,13,14,1,2,15,16,17]
slice_ = [2, 4, 6, 8, 10, 12, 15, 17, 20, 22]
intervals = [12, 17, 22]

Categories