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
Related
normal = ['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']
modified = ['s', 'n', 'v', 'f', 'r', 'g', 'h', 'j', 'o', 'k', 'l', 'a',
'z', 'm', 'p', 'q', 'w', 't', 'd', 'y', 'i', 'b', 'e', 'c', 'u', 'x']
word = input()
for char in word:
if char in normal:
char.replace(char, modified)
This is what i have so far,
I want to be able to type in a sentence and it will output the sentence with the modified alphabets
one of the way to map the normal list character with the modified list character and replace them in the sentence.
normal = ['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']
modified = ['s', 'n', 'v', 'f', 'r', 'g', 'h', 'j', 'o', 'k', 'l', 'a',
'z', 'm', 'p', 'q', 'w', 't', 'd', 'y', 'i', 'b', 'e', 'c', 'u', 'x']
mapper = {}
for a, b in zip(normal, modified):
mapper[b] = a
word ="this is user commented word"
# new_word = ' '.join(map(lambda x: ''.join(mapper[i] for i in x), word.split()))
new_word = []
for i in word.split():
tmp = []
for j in i:
tmp.append(mapper[j])
new_word.append(''.join(tmp))
new_sentence = ' '.join(new_word)
print(new_sentence)
output
rgua ua yawe xinnwbrws qies
normal = 'abcdefghijklmnopqrstuvwxyz'
modified = 'lvxswdfguhjknbiopearycqztm'
word = input()
convert = str.maketrans(normal, modified)
print(word.translate(convert))
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']]
I have a list of lists:
[['w1 a b c'], ['w2 d e f g h i'], ['w3 j k l m n o p q', 'w5 r s t u v w x']...]
I want to split by space, but keeping w3 and w5 item together:
for i in listoflists:
for j in i:
j.split(' ')
[['w1', 'a', 'b', 'c']
['w2', 'd', 'e', 'f', 'g', 'h', 'i']
['w3', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q']
['w5', 'r', 's', 't', 'u', 'v', 'w', 'x']...]
the desired output would be:
[['w1', 'a', 'b', 'c']
['w2', 'd', 'e', 'f', 'g', 'h', 'i']
[['w3', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q'], ['w5', 'r', 's', 't', 'u', 'v', 'w', 'x']]...]
Try the following:
result=[]
for i in listoflists:
if len(i)==1:
result.append(i[0].split(' '))
else:
result.append([k.split(' ') for k in i])
>>>print(result)
[['w1', 'a', 'b', 'c'], ['w2', 'd', 'e', 'f', 'g', 'h', 'i'], [['w3', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q'], ['w5', 'r', 's', 't', 'u', 'v', 'w', 'x']]]
Try
out = [
[y.split(' ') for y in x] if len(x) > 1 else x.pop().split(' ')
for x in listoflists
]
Output
[print(a) for a in out]
['w1', 'a', 'b', 'c']
['w2', 'd', 'e', 'f', 'g', 'h', 'i']
[['w3', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q'], ['w5', 'r', 's', 't', 'u', 'v', 'w', 'x']]
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']
Is there a built-in method / module in Python to generate letters such as the built-in constant LETTERS or letters constant in R?
The R built-in constant works as letters[n] where if n = 1:26 the lower-case letters of the alphabet are produced.
Thanks.
It's called string.ascii_lowercase.
If you wanted to pick n many random lower case letters, then:
from string import ascii_lowercase
from random import choice
letters = [choice(ascii_lowercase) for _ in range(5)]
If you wanted it as a string, rather than a list then use str.join:
letters = ''.join([choice(ascii_lowercase) for _ in range(5)])
You can use map as in the following:
>>> map(chr, range(65, 91))
['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']
>>> map(chr, range(97, 123))
['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 = map(chr, range(65, 70))
>>> a
['A', 'B', 'C', 'D', 'E']
With list comprehensions and reference from the above, there is another method:
>>> [chr(x) for x in range(97, 123)]
['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']
Yet another way to do it which will give you directly a string:
>>> bytearray(range(97,123)).decode("utf-8")
u'abcdefghijklmnopqrstuvwxyz'
(it works with both python2 and python3, of course the u prefix won't be visible if it's python 3)
You can obviously tranform that string into a list like in other answers if that is what you prefer, for instance with:
>>> [x for x in bytearray(range(97,123)).decode("utf-8")]
['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']
It is also very easy to change it to pick n random letters (repetition allowed):
>>> import random
>>> n = 10
>>> bytearray(random.randint(97, 122) for x in range(n)).decode('utf-8')
'qdtdlrqidx'
Or without repetition:
>>> import random
>>> n = 10
>>> bytearray(random.sample(range(97, 123),n)).decode('utf-8')
'yjaifemwbr'