From an initial list:
starting_list = [
[1,2,3, 4,5,6, 7,8,9 ],
[11,22,33, 44,55,66, 77,88,99 ],
[111,222,333, 444,555,666, 777,888,999]
]
I would like to create a new list (either using a for loop or list comprehension) whose elements are the sub-lists of starting_list, grouped by three elements and starting at every third index:
grouped_by_3_elements = [
[1,2,3, 11,22,33, 111,222,333],
[4,5,6, 44,55,66, 444,555,666],
[7,8,9, 77,88,99, 777,888,999]
]
I have managed the following, but not exactly what I am looking for
[ [1, 2, 3], [11, 22, 33], [111, 222, 333], [4, 5, 6], [44, 55, 66], [444, 555, 666], [7, 8, 9], [77, 88, 99], [777, 888, 999] ]
Thanks
••• UPDATE •••
For those who want to know what I did to arrive at my current solution:
lst = [
[1,2,3,4,5,6,7,8,9],
[11,22,33,44,55,66,77,88,99],
[111,222,333,444,555,666,777,888,999]
]
new_lst = []
for col in range(0, len(lst[0]), 3):
for row in range(3):
new_lst.append(lst[row][col:col+3])
print(new_lst)
>>> [[1, 2, 3], [11, 22, 33], [111, 222, 333], [4, 5, 6], [44, 55, 66], [444, 555, 666], [7, 8, 9], [77, 88, 99], [777, 888, 999]]
Can I somehow arrive at my desired
[
[1,2,3, 11,22,33, 111,222,333],
[4,5,6, 44,55,66, 444,555,666],
[7,8,9, 77,88,99, 777,888,999]
]
without having to run my result (new_lst) through a separate loop in order to repack ?
Changing yours just a little:
new_lst = []
for col in range(0, len(lst[0]), 3):
inner = []
for row in range(3):
inner += lst[row][col:col+3]
new_lst.append(inner)
Changing it a bit more:
new_lst = []
for col in range(0, len(lst[0]), 3):
inner = []
for row in lst:
inner += row[col:col+3]
new_lst.append(inner)
Older solution from before there was an indication for other sizes:
Similar to an ordinary transposition of a 3×3 matrix, just with slices in the rows:
a = starting_list
for i in range(3):
si = slice(i*3, i*3+3)
for j in range(i):
sj = slice(j*3, j*3+3)
a[i][sj], a[j][si] = a[j][si], a[i][sj]
You can use sub ranges in a nested comprehension:
L = [
[1,2,3, 4,5,6, 7,8,9 ],
[11,22,33, 44,55,66, 77,88,99 ],
[111,222,333, 444,555,666, 777,888,999]
]
r = [ [ n for r in L for n in r[c:c+3] ] for c in range(0,len(L[0]),3) ]
print(r)
[[1, 2, 3, 11, 22, 33, 111, 222, 333],
[4, 5, 6, 44, 55, 66, 444, 555, 666],
[7, 8, 9, 77, 88, 99, 777, 888, 999]]
end_list = []
sublist_len = min(len(lst) for lst in starting_list)
for i in range(0, sublist_len, 3):
group = []
for lst in starting_list:
group.append(lst[i:i+3])
end_list.append([y for x in group for y in x])
First we start with an empty list. We calculate the length of the sublists so we don't get any out of bounds errors indexing the sublists.
We then iterate over indexes for "chunks" of these sublists. 0, 1, 2, 3, 4, 5, etc.
For each of these chunks of indexes, we create a group by appending a slice of the list to group for each sublist. At the end of that loop, we use some list comprehension logic to "flatten" the list of lists we've created, and append that list to the end_list list.
End result?
[[1, 2, 3, 11, 22, 33, 111, 222, 333], [4, 5, 6, 44, 55, 66, 444, 555, 666], [7, 8, 9, 77, 88, 99, 777, 888, 999]]
We can also use a list comprehension to accomplish this, using the same sublist_len as before. The logic is the same as before, but more direct. for i in range(0, sublist_len, 3) will yield 0, 3, and 6. We then map each of these to a list created by the nested list comprehension.
end_list = [[x for lst in starting_list for x in lst[i:i+3]] for i in range(0, sublist_len, 3)]
Related
I want to create a NxN matrix (represented as lists of lists), where the first n-1 columns have random numbers in the range 1 to 10, and the last column contains the result of adding the numbers in previous commons.
import random
randomlist1 = []
for i in range(1,10):
n = random.randint(1,100)
randomlist1.append(n)
print(randomlist1)
randomlist2 = []
for i in range(1,10):
n = random.randint(1,100)
randomlist2.append(n)
print(randomlist2)
randomlist3 = []
for i in range(1,10):
n = random.randint(1,100)
randomlist3.append(n)
print(randomlist3)
# I have problems here
lists_of_lists = [sum(x) for x in (randomlist1, randomlist2,randomlist3)]
[sum(x) for x in zip(*lists_of_lists)]
print(lists_of_lists)
Your question calls for a few comments:
the title does not correspond to the question, and the code matches the title, not the question;
the rows randomlist1 , randomlist1 , randomlist1 are not in a matrix;
the final value is not a square matrix;
You write "the columns have random numbers in the range of 1 to 10" but your code randint(1,100) creates numbers in the range [1..100].
Solution to the question
import random
N = 5
# create a N by N-1 matrix of random integers
matrix = [[random.randint(1, 10) for j in range(N-1)] for i in range(N)]
print(f"{N} by {N-1} matrix:\n{matrix}")
# add a column as sum of the previous ones
for line in matrix:
line.append(sum(line))
print(f"{N} by {N} matrix with the last column as sum of the previous ones:\n{matrix}")
Ouput:
5 by 4 matrix:
[[7, 10, 5, 6], [4, 10, 9, 3], [5, 5, 4, 9], [10, 7, 2, 4], [8, 8, 5, 3]]
5 by 5 matrix with the last column as sum of the previous ones:
[[7, 10, 5, 6, 28], [4, 10, 9, 3, 26], [5, 5, 4, 9, 23], [10, 7, 2, 4, 23], [8, 8, 5, 3, 24]]
IIUC try with numpy
import numpy as np
np.random.seed(1) # just for demo purposes
# lists comprehensions to create your 3 lists inside a list
lsts = [np.random.randint(1,100, 10).tolist() for i in range(3)]
np.sum(lsts, axis=0)
# array([145, 100, 131, 105, 215, 115, 194, 247, 116, 45])
lsts
[[38, 13, 73, 10, 76, 6, 80, 65, 17, 2],
[77, 72, 7, 26, 51, 21, 19, 85, 12, 29],
[30, 15, 51, 69, 88, 88, 95, 97, 87, 14]]
Based on #It_is_Chris answer, I propose this as a numpy only implementation, without using lists:
np.random.seed(1)
final_shape = (3, 10)
lsts = np.random.randint(1, 100, np.prod(final_shape)).reshape(final_shape)
lstsum = np.sum(lsts, axis=0)
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]
If I create lists to hold a column each for what will be a database table. How would I loop though the ID list to add one row at a time to a new object. So each object will hold one row for what will be a database table.
Example Lists
ListID[1,2,3,4,5]
List1[34,56,34,345,55]
list2[644,64,232,44,1]
list3[622,12,44,55,01]
I then want to create a function that will iterate though ListID and create a 'list object' eg, [1, 34, 644, 622] would be the first object then [2, 56, 64, 12]. I'm not sure how to preform this but keep it in a format that can still be persisted to a database table
If I understood correctly, you could do something like that, using zip:
ListID = [1,2,3,4,5]
List1 = [34,56,34,345,55]
list2 = [644,64,232,44,1]
list3 = [622,12,44,55,1]
objectList = [list(elem) for elem in zip(ListID,List1,list2,list3)]
print(objectList)
Output:
[[1, 34, 644, 622], [2, 56, 64, 12], [3, 34, 232, 44], [4, 345, 44, 55], [5, 55, 1, 1]]
An alternative would be to use map function, along with zip:
objectList = list(map(lambda elem: list(elem), zip(ListID,List1,list2,list3)))
You can use dictionary combined with zip, and this way you can also retrieve data using ListID:
ListID = [1,2,3,4,5]
List1 = [34,56,34,345,55]
List2 = [644,64,232,44,1]
List3 = [622,12,44,55,1]
dictObj = {}
for ID, l1, l2, l3 in zip(ListID, List1, List2, List3):
dictObj[f'{ID}'] = [ID, l1, l2, l3]
If you don't want to use any third-party libraries like pandas, you can use defaultdict for an easy implementation:
from collections import defaultdict
dd = defaultdict(list)
listID = [1,2,3,4,5]
list1 = [34,56,34,345,55]
list2 = [644,64,232,44,1]
list3 = [622,12,44,55,1]
for idx, c1, c2 in zip(listID,list1, list2):
dd[idx].extend([c1, c2])
dd
# defaultdict(list,
# {1: [34, 644],
# 2: [56, 64],
# 3: [34, 232],
# 4: [345, 44],
# 5: [55, 1]})
for idx, item in zip(listID,list3):
dd[idx].append(item)
dd
# defaultdict(list,
# {1: [34, 644, 622],
# 2: [56, 64, 12],
# 3: [34, 232, 44],
# 4: [345, 44, 55],
# 5: [55, 1, 1]})
I am not able to remove composite numbers from a list in python 3 .Can you help?
Example input:
list1 = [2, 3, 6, 7, 14, 21, 23, 42, 46, 69, 138, 161, 322, 483]
Expected output:
list1 = [2, 3, 7, 23]
Thanks in advance.
You can use a list comprehension with all:
list1 = [2, 3, 6, 7, 14, 21, 23, 42, 46, 69, 138, 161, 322, 483]
new_result = [i for i in list1 if all(i%c != 0 for c in range(2, i))]
Output:
[2, 3, 7, 23]
Ajax1234's solution is correct, but instead of using range(2, i), I would add the modification that range(2, i) becomes range(2, 1+math.ceil(math.sqrt(i))), where the math module has been imported. For very large lists, this reduces the execution time since all composite numbers have factors less than or equal to 1+math.ceil(math.sqrt(i)).
I'm trying to remove values from a large data set that are inconsistent in my analysis.
Here is the current method i'm started with.
For example, lets say I have an array a that consist of an number of elements.
a = [30, 40, 200, 324, 8, 67, 789, 9, 567, 2143, 13]
idx = [(i,value) for i,value in enumerate(a) if value<=10]
print idx
>>> [(4, 8), (7, 9)]
How do i go about to where I can only just create an array that consist of only its indices
print idx
>>> [4, 8]
Don't include the value in the comprehension result:
idx = [i for i, v in enumerate(a) if v <= 10]
You are almost there, just only use the index:
>>> a = [30, 40, 200, 324, 8, 67, 789, 9, 567, 2143, 13]
>>> idx = [i for i, value in enumerate(a) if value<=10]
>>> idx
[4, 7]