This question already has answers here:
How do I split a list into equally-sized chunks?
(66 answers)
Closed 6 years ago.
I'm trying to create and initialize a matrix. Where I'm having an issue is that each row of my matrix I create is the same, rather than moving through the data set.
I've tried to correct it by checking if the value was already in the matrix and that didn't solve my problem.
def createMatrix(rowCount, colCount, dataList):
mat = []
for i in range (rowCount):
rowList = []
for j in range (colCount):
if dataList[j] not in mat:
rowList.append(dataList[j])
mat.append(rowList)
return mat
def main():
alpha = ['a','b','c','d','e','f','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
mat = createMatrix(5,5,alpha)
print (mat)
The output should be like this:
['a','b','c','d','e'] , ['f','h','i','j','k'], ['l','m','n','o','p'] , ['q','r','s','t','u'], ['v','w','x','y','z']
My issue is I just keep getting the first a,b,c,d,e list for all 5 lists returned
You need to keep track of the current index in your loop.
Essentially you want to turn a list like 0,1,2,3,4,....24 (these are the indices of your initial array, alpha) into:
R1C1, R1C2, R1C3, R1C4, R1C5
R2C1, R2C2... etc
I added the logic to do this the way you are currently doing it:
def createMatrix(rowCount, colCount, dataList):
mat = []
for i in range(rowCount):
rowList = []
for j in range(colCount):
# you need to increment through dataList here, like this:
rowList.append(dataList[rowCount * i + j])
mat.append(rowList)
return mat
def main():
alpha = ['a','b','c','d','e','f','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
mat = createMatrix(5,5,alpha)
print (mat)
main()
which then prints out:
[['a', 'b', 'c', 'd', 'e'], ['f', 'h', 'i', 'j', 'k'], ['l', 'm', 'n', 'o', 'p'], ['q', 'r', 's', 't', 'u'], ['v', 'w', 'x', 'y', 'z']]
The reason you were always receiving a,b,c,d,e is because when you write this:
rowList.append(dataList[j])
what it is effectively doing is it is iterating 0-4 for every row. So basically:
i = 0
rowList.append(dataList[0])
rowList.append(dataList[1])
rowList.append(dataList[2])
rowList.append(dataList[3])
rowList.append(dataList[4])
i = 1
rowList.append(dataList[0]) # should be 5
rowList.append(dataList[1]) # should be 6
rowList.append(dataList[2]) # should be 7
rowList.append(dataList[3]) # should be 8
rowList.append(dataList[4]) # should be 9
etc.
You can use a list comprehension:
>>> li= ['a','b','c','d','e','f','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
>>> [li[i:i+5] for i in range(0,len(li),5)]
[['a', 'b', 'c', 'd', 'e'], ['f', 'h', 'i', 'j', 'k'], ['l', 'm', 'n', 'o', 'p'], ['q', 'r', 's', 't', 'u'], ['v', 'w', 'x', 'y', 'z']]
Or, if you don't mind tuples, use zip:
>>> zip(*[iter(li)]*5)
[('a', 'b', 'c', 'd', 'e'), ('f', 'h', 'i', 'j', 'k'), ('l', 'm', 'n', 'o', 'p'), ('q', 'r', 's', 't', 'u'), ('v', 'w', 'x', 'y', 'z')]
Or apply list to the tuples:
>>> map(list, zip(*[iter(li)]*5))
[['a', 'b', 'c', 'd', 'e'], ['f', 'h', 'i', 'j', 'k'], ['l', 'm', 'n', 'o', 'p'], ['q', 'r', 's', 't', 'u'], ['v', 'w', 'x', 'y', 'z']]
Related
This question already has answers here:
Iterate an iterator by chunks (of n) in Python?
(14 answers)
Closed 2 years ago.
Here's a list that I have,
data = (i for i in list("abcdefghijklmnopqrstuvwxyzabcedefghijklmnopqrstuvwxyz"))
Here data is a generator and I want to iterate over it and prepared batches of 12 equal datapoints, if it is less than 12 in last batch I need it too, but below code is not working,
subsets = []
subset = []
for en, i in enumerate(data):
if en % 12 == 0 and en > 0:
subsets.append(subset)
subset = []
else:
subset.append(i)
print(subsets)
[['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'],
['n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x'],
['z', 'a', 'b', 'c', 'e', 'd', 'e', 'f', 'g', 'h', 'i'],
['k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u']]
But my code is not working properly because the first nested list has 12 values but rest of it have 11 values and it missed out last few values which are less than 12 in the last batch
Expected Output:
[['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'],
['m', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x'],
['y', 'z', 'a', 'b', 'c', 'e', 'd', 'e', 'f', 'g', 'h', 'i'],
['j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u'],
['v', 'w', 'x', 'y', 'z']]
Two changes, you need to start iterating from 1 and append in the sublist before emptying it:
data = (i for i in list("abcdefghijklmnopqrstuvwxyzabcedefghijklmnopqrstuvwxyz"))
subsets = []
subset = []
# start counting from index '1'
for en, i in enumerate(data, 1):
if en % 12 == 0 and en > 0:
# append the current element before emptying 'subset'
subset.append(i)
subsets.append(subset)
subset = []
else:
subset.append(i)
# append the left-over sublist/subset to your main list as well
subsets.append(subset)
for i in subsets:
print(i)
gives
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l']
['m', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x']
['y', 'z', 'a', 'b', 'c', 'e', 'd', 'e', 'f', 'g', 'h', 'i']
['j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u']
['v', 'w', 'x', 'y', 'z']
Alternative solution is using buit-in itertools.islice. You can check to see which approach is faster or more convenient. Kr.
import itertools
def gen_sublist(your_iter, size):
while True:
part = tuple(itertools.islice(your_iter, size))
if not part:
break
yield part
data = (i for i in list("abcdefghijklmnopqrstuvwxyzabcedefghijklmnopqrstuvwxyz"))
for c in gen_sublist(data, size=12):
print(c)
which returns:
('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l')
('m', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x')
('y', 'z', 'a', 'b', 'c', 'e', 'd', 'e', 'f', 'g', 'h', 'i')
('j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u')
('v', 'w', 'x', 'y', 'z')
A different approach which does not use modulo or enumeration (just another option since other answers already correct your approach):
In [1]: subsets = []
In [2]: data = (i for i in list("abcdefghijklmnopqrstuvwxyzabcedefghijklmnopqrstuvwxyz"))
In [3]:
...: while True:
...: try:
...: x = []
...: for i in range(12):
...: x.append(next(data))
...: subsets.append(x)
...: except: # Catch StopIteration Exception when generator runs out of values
...: subsets.append(x)
...: break
...:
Outputs:
In [4]: subsets
Out[4]:
[['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'],
['m', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x'],
['y', 'z', 'a', 'b', 'c', 'e', 'd', 'e', 'f', 'g', 'h', 'i'],
['j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u'],
['v', 'w', 'x', 'y', 'z']]
How to write a code to identify indexes where a shift happens and fetch corresponding value from another array in python?
array1 = (0,0,0,1,1,1,1,1,2,2,2,2,3,3,3,2,2,2,3,3,3,3,3,1,1,1)
array2 = ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z')
The final output should be two arrays, one should contain elements fetched from array2 and the other should contain index numbers of the shifts.
Desired Output:
Indexes: [3, 8, 12, 15, 18, 23]
Final: ['d', 'i', 'm', 'p', 's', 'x']
Here is a solution
array1= [0,0,0,1,1,1,1,1,2,2,2,2,3,3,3,2,2,2,3,3,3,3,3,1,1,1]
array2= ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
cur=array1[0]
indxes=[]
final=[]
for i in range(1,len(array1)):
if array1[i]!=cur:
cur=array1[i]
indxes.append(i)
final.append(array2[i])
print(indxes)
print(final)
Here is a possible solution:
indexes = [i for i in range(1, len(array1)) if array1[i-1] != array1[i]]
final = [array2[i] for i in indexes]
This question already has answers here:
Python recursion permutations
(13 answers)
Closed 3 years ago.
So been struggling with this one, I'm close and have finally found a way to somewhat desired output now repeats in generated list.
input['a','r','t']
def permutations(string_list):
if len(string_list) <= 1:
return [string_list]
perm_list = []
for letter_index in range(len(string_list)):
perms_1 = string_list[letter_index]
rest = string_list[:letter_index] + string_list[letter_index + 1:]
for perms_2 in permutations(rest):
perm_list.append([perms_1] + perms_2)
return perm_list
output
[[['a', 'r', 't'], ['a', 't', 'r'], ['r', 'a', 't'], ['r', 't', 'a'],
['t', 'a', 'r'], ['t', 'r', 'a']], [['a', 'r', 't'], ['a', 't', 'r'],
['r', 'a', 't'],
.........repeats.......repeats..
..for quite sometime but not infinite....]]]
DESIRED output
[['a', 'r', 't'], ['a', 't', 'r'], ['r', 'a', 't'], ['r', 't', 'a'],
['t', 'a', 'r'], ['t', 'r', 'a']]
so it's permutation but what is tripping me up is having to use the list of strings and outputting a list of lists of strings. I have redone this multiple time and have the basis of recursive permutations down if I was just using a string 'art' as input or having a list output ['art','atr','rat',ect..] just not sure where I am going wrong. No import of itertools allowed and really wish I didn't need for loops but using comprehension recursion call gives me same results...any help or pointers appreciated. Not looking for just a redo I want to understand....
Using this, you get the desired output:
from itertools import permutations
inp = ['a', 'r', 't']
list(permutations(inp, 3))
Out:
[('a', 'r', 't'),
('a', 't', 'r'),
('r', 'a', 't'),
('r', 't', 'a'),
('t', 'a', 'r'),
('t', 'r', 'a')]
The result is a list of tuples, but you can convert them to lists if you want.
def permute(input, l, r, arr = []):
if l == r:
arr.append(input)
else:
for i in range(l, r + 1):
input[l], input[i] = input[i], input[l]
permute(input, l + 1, r, arr)
input[l], input[i] = input[i], input[l]
return arr
input = ['a','r','t']
n = len(input)
print (permute(input, 0, n - 1))
result:
[['a', 'r', 't'], ['a', 'r', 't'], ['a', 'r', 't'], ['a', 'r', 't'], ['a', 'r', 't'], ['a', 'r', 't']]
NOTE: You are missing else statement
I'm attempting to do work with lists in Python and there is a certain part I've been stuck on:
Objective: Iterate through a master list (alphabet) of x amount of elements, and compare whether the index of said element is a factor of 7. If so, append this element to a new list (final). It seems very simple, and here is the code I've written so far:
def test():
alphabet = ['a', 'a', 'b' 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'li', 'a']
final = []
for letter in alphabet:
if (alphabet.index(letter) % 7 == 0):
final.append(letter)
print final
The output I am getting: ['a', 'a', 'g', 'n', 'u', 'a']
The output I am expecting should return a list of every element in the original list that has an index divisible by 7. I cannot figure out how to account for the duplicates.
Any assistance with this would be much appreciated - thank you very much in advance!
Do:
>>> a = ['a', 'a', 'b' 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'li', 'a']
>>> [j for i,j in enumerate(a) if i%7==0]
['a', 'g', 'n', 'u', 'a']
Note that, on index 2, you have 'b' 'b' which results in 'bb'.
I think this is what you're after
for index, letter in enumerate(alphabet):
if (index % 7 == 0):
final.append(letter)
print final
Two things.
First, instead of using a list to accumulate the results, use a set. Duplicates are automatically eliminated.
And, why look at every letter instead of just at every seventh letter?
final = set()
for i in range(len(alphabet)/7):
final.add(alphabet[i*7])
print final
try this:
>>> alphabet = ['a', 'a', 'b' 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'li', 'a']
>>> [letter for i,letter in enumerate(alphabet) if i%7==0]
['a', 'g', 'n', 'u', 'a']
I am working on creating a playfair cipher for python and I am having trouble indexing the location of a letter in the table provided below.
[['A', 'B', 'C', 'D', 'E'],
['F', 'G', 'H', 'I', 'Y'],
['K', 'L', 'M', 'N', 'O'],
['P', 'Q', 'R', 'S', 'T'],
['U', 'V', 'W', 'X', 'Z']]
I was wondering how I would be able to find the location of a letter in the table which gives an output of row and column.
I've looked online for different solutions, but I can't seem to make it work properly.
Is this what you're looking for?
def find_index(table, letter):
for r_index, row in enumerate(table):
if letter in row:
return (r_index, row.index(letter))
You iterate through the table, and search for the index of the letter in each row.
Alternatively, if you're constantly searching in the matrix, it might be more efficient to convert it to a dict so you get O(1) access:
def get_index_map(table):
output = {}
for r_index, row in enumerate(table):
for c_index, letter in enumerate(row):
output[letter] = (r_index, c_index)
return output
Then, you can just call this function once at the start of your program, and use the returned dict to find the row and column number of each letter.
My take:
>>> lst = [['A', 'B', 'C', 'D', 'E'],
... ['F', 'G', 'H', 'I', 'Y'],
... ['K', 'L', 'M', 'N', 'O'],
... ['P', 'Q', 'R', 'S', 'T'],
... ['U', 'V', 'W', 'X', 'Z']]
>>> get = "S"
>>> {x:y.index(get) for x,y in enumerate(lst) if get in y}
{3: 3}
>>> get = "V"
>>> {x:y.index(get) for x,y in enumerate(lst) if get in y}
{4: 1}
>>>
data = [['A', 'B', 'C', 'D', 'E'],
['F', 'G', 'H', 'I', 'Y'],
['K', 'L', 'M', 'N', 'O'],
['P', 'Q', 'R', 'S', 'T'],
['U', 'V', 'W', 'X', 'Z']]
search = "I"
for rowIdx, row in enumerate(data):
if search in row:
print rowIdx, row.index(search)
break
Output
1 3
from itertools import product
li = [['A', 'B', 'C', 'D', 'E'],
['F', 'G', 'H', 'I', 'Y'],
['K', 'L', 'M', 'N', 'O'],
['P', 'Q', 'R', 'S', 'T'],
['U', 'V', 'W', 'X', 'Z']]
letter = 'P'
for i, j in product(range(len(li)),range(len(li[0]))):
if li[i][j] == letter:
print (i,j)
break
Here is my weird way. :) Note: Python 2.7 so / means integer division.
table = [['A', 'B', 'C', 'D', 'E'],
['F', 'G', 'H', 'I', 'Y'],
['K', 'L', 'M', 'N', 'O'],
['P', 'Q', 'R', 'S', 'T'],
['U', 'V', 'W', 'X', 'Z']]
tablestring = ''.join(''.join(row) for row in table)
x = tablestring.index('V')
i = x / (len(tablestring) / len(table))
j = x % (len(tablestring) / len(table))
print i, j
print table[i][j]
Prints:
4 1
V
Here is another way:
matrix=[['A', 'B', 'C', 'D', 'E'],
['F', 'G', 'H', 'I', 'Y'],
['K', 'L', 'M', 'N', 'O'],
['P', 'Q', 'R', 'S', 'T'],
['U', 'V', 'W', 'X', 'Z']]
def index(letter, matrix):
for i,li in enumerate(matrix):
try:
j=li.index(letter)
return i,j
except ValueError:
pass
raise ValueError("'{}' not in matrix".format(letter))
print index('H', matrix)
# (1, 2)
print index('a', matrix)
# ValueError