Suppose i have a matrix like this
table = [
# grid: 4 by 9
['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','1','2'],
['3','4','5','5'],
['7','8','9','0'],
]
If i want to print the the string thats two down on the third column(2x,3y) resulting in G. Or something along the lines. How do i tell python that it should be a grid? And how do i return list information, the table.find(something) did not work (saying table has no find attribute) Im fairly new to python. I have searched the internet, with not much help..
edit: I must be doing something wrong?
table = [
# grid: 4 by 9
# 1 2 3 4
['A','B','C','D'],#1
['E','F','G','H'],#2
['I','J','K','L'],#3
['M','N','O','P'],#4
['Q','R','S','T'],#5
['U','V','W','X'],#6
['Y','Z','1','2'],#7
['3','4','5','5'],#8
['7','8','9','0'],#9
]
print table[1][2], table[4][3]
Prints O and T.
O is right, but T is not, thats row 5 isnt it?'
I'm trying to write a text positional encryption algorithm with text matrixes, like one of the famous ciphers( i cant remember the name of).
I want to apply the said printing of each letter to the text that is caught by raw_input, i used dictionaries before, but i want to try this row/column method if possible, it will be much harder to break.
table[1][2] would give the value in the second row, third column (since indices start at 0).
More specifically, what you're specifying is a list of lists, so table[1] would resolve to ['E','F','G','H'] (the second item in the overall list), and then taking the third element of that with [2] would give you 'G'.
List indexing starts at zero, so for example a fourth element in a list has index 3. You can define a helper function to get items/columns by their "actual position".
def column(matrix, i):
return [row[i-1] for row in matrix]
column(table,2)
Out[15]:
['B', 'F', 'J', 'N', 'R', 'V', 'Z', '4', '8']
def getitem(matrix,row,column):
return matrix[row-1][column-1]
getitem(table,2,3)
Out[16]:
'G'
As for your edit, table[1][2] should print G, not O and table[4][3] rightly returns T.
table = [
['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','1','2'],
['3','4','5','5'],
['7','8','9','0'],
]
# grid 4 by 9, 4 column, 9 row
rownum=3
colnum=2
print(table[rownum-1][colnum-1])
Are you referring to http://en.wikipedia.org/wiki/Vigenere_cipher ?
If you want to work with matrices, then numpy is recommended (a simple example):
>>> import numpy as np
>>> a = np.array(table)
>>> a
array([['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', '1', '2'],
['3', '4', '5', '5'],
['7', '8', '9', '0']],
dtype='|S1')
>>> print a[1,2]
G
>>> np.where(a=='G')
(array([1]), array([2]))
There's also an oft over looked string method that can be used to substitute text (however you decide to do it)...
>>> from string import maketrans
>>> trans = maketrans('AB', 'XY') # A->X, B->Y, everything else unchanged
>>> 'ABC'.translate(trans)
'XYC'
Related
I am wondering if there is a way to iterate over individual positions in a sequence list using NumPy. For example, if I had a list of sequences:
a = ['AGHT','THIS','OWKF']
The function would be able to go through each individual characters in their position. So for the first sequence 'AGHT', it would be broken down into 'A','G','H','T'. The ultimate goal is to create individual grids based on character abundance in each one of these sequences. So far I have only been able to make a loop that goes through each character, but I need this in NumPy:
b = np.array(a)
for c in b:
for d in c:
print(d)
I would prefer this in NumPy, but if there are other ways I would like to know as well. Thanks!
list expands a string into a list:
In [406]: a = ['AGHT','THIS','OWKF']
In [407]: [list(item) for item in a]
Out[407]: [['A', 'G', 'H', 'T'], ['T', 'H', 'I', 'S'], ['O', 'W', 'K', 'F']]
You can use join() to join the array into a sequence of characters, then iterate over each character or print it like this:
>>> a = ['AGHT','THIS','OWKF']
>>> print(''.join(a))
'AGHTTHISOWKF'
Or to turn it into an array of individual characters:
>>> out = ''.join(a)
>>> b = np.array(list(out))
array(['A', 'G', 'H', 'T', 'T', 'H', 'I', 'S', 'O', 'W', 'K', 'F'],
dtype='<U1')
I have the following lists:
['4', 'H']['K', 'H']['6', 'H']['6', 'D']['4', 'H']['Q', 'C']['8', 'D']
Is it possible to import these into python without manually adding commas between each one?
I've tried assigning it to a variable like:
b = ['4', 'H']['K', 'H']['6', 'H']['6', 'D']['4', 'H']['Q', 'C']['8', 'D']
but I get:
TypeError: list indices must be integers or slices, not tuple
You're trying to assign multiple lists to a single variable and that's not allowed
Try this.
Wrap all of the lists in another list so that you can place it inside the variable
b = [['4', 'H'],['K', 'H'],['6', 'H'],['6', 'D'],['4', 'H'],['Q', 'C'],['8', 'D']]
And to access it just do this.
b[0][0] // Output: 4
This is now called a multi-dimensional list
This is a pretty messy return you're getting, but if you replace the middle ] values with ], wrap it all in a list, and swap the single quotes for doubles, you can parse it as JSON:
In [121]: s = "['4', 'H']['K', 'H']['6', 'H']['6', 'D']['4', 'H']['Q', 'C']['8', 'D']"
In [122]: json.loads('[{}]'.format(s.replace("]", "],").replace("'", '"')[:-1]))
Out[122]:
[['4', 'H'],
['K', 'H'],
['6', 'H'],
['6', 'D'],
['4', 'H'],
['Q', 'C'],
['8', 'D']]
Im using a function to parse an excel in python without using libraries but importing an individual script accessing the excel data. my program can read the excel data and with following structure gets the values. I need to access specific columns of the listExcelvalues as follow and pay it to the input of other function :
actual code
ive converted the list into the dict but the problem is I dont want to pass all the dictionary as input of other function but instead specific columns.
Any ideas how to do so ?
As I understand you have a structure like this:
>>> l=[['a','b','c','d'],['e','f','g','h'],['i','j','k','l'],['m','n','o','p']]
>>> m=list(enumerate(l,0))
>>> m
[(0, ['a', 'b', 'c', 'd']), (1, ['e', 'f', 'g', 'h']), (2, ['i', 'j', 'k', 'l']), (3, ['m', 'n', 'o', 'p'])]
Then you can access rows like this. Here is the second row (counting from zero):
>>> row=m[2][1]
>>> row
['i', 'j', 'k', 'l']
>>> hrow=m[2]
>>> hrow
(2, ['i', 'j', 'k', 'l'])
And columns too. Here is the second (counting from zero) column:
>>> col=[]
>>> for r in m:
... col.append(r[1][2])
>>> col
['c', 'g', 'k', 'o']
You want to take a subset of your dict. You may want to try this out:
new_dict = {k:v if k in list_of_req_cols for k,v in original_dict.items()}
Before anything: I did read Wrapping around a python list as a slice operation and wrapping around slices in Python / numpy
This question is not a duplicate of any of those two questions simply because this question is a totally different question. So stop downvoting it and do not mark it as a duplicate. In the first mentioned thread, the "wrap" there means something different. For the second mentioned thread, they dealt with ndarray and can only work for integers only.
Real question:
How to slice a string or an array from a point to another point with an end between them?
Essentially, we want to do something like this,
n = whatever we want
print(string[n-5:n+6])
The above code may look normal. But it doesn't work near the edges (near the beginning of the string/array or the end of the string/array). Because Python's slicing doesn't allow slicing through the end of the array and continuing from the beginning. What if n is smaller than 5 or length of string longer than n+6?
Here's a better example, consider that we have
array = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']
We want to print an element with its nearest two neighbors in string for all elements in an array
print("Two neighbors:")
for i, x in enumerate(array):
print(array[i-1] + array[i] + array[(i+1)%len(array)])
Output:
Two neighbors:
kab
abc
bcd
cde
def
efg
fgh
ghi
hij
ijk
jka
So far so good, let's do it with four neighbors.
print("Four neighbors:")
for i, x in enumerate(array):
print(array[i-2] + array[i-1] + array[i] + array[(i+1)%len(array)] + array[(i+2)%len(array)])
Output:
Four neighbors:
jkabc
kabcd
abcde
bcdef
cdefg
defgh
efghi
fghij
ghijk
hijka
ijkab
You can see where this is going, as the desired number of neighbors grow, the number of times we must type them out one by one increases.
Is there a way instead of s[n-3]+s[n-2]+s[n-1]+s[n]+s[n+1]+s[n+2]+s[n+3], we can do something like s[n-3:n+4]?
Note that s[n-3:n]+s[n:(n+4)%len(s)] doesn't work at the edges.
NOTE:
For the particular example above, it is possible to do a 3*array or add a number of elements to the front and to the back to essentially "pad" it.
However, this type of answer cost a bit of memory AND cannot work when we want to wrap it many folds around.
Consider the following,
# len(string) = 10
# n = 0 or any number we want
print(string[n-499:n+999])
If the start and end indices can be flexible instead of mirroring each other(eg. string[n-2:n+9] instead of string[n-3:n+4]), it is even better.
A solution which doesn't use an excessive amount of memory is as follows
my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9]
def get_sequences(a_list, sequence_length):
sequences = []
for i in range(len(my_list)):
sequences.append("".join(str(my_list[(x + i) % len(my_list)]) for x in range(sequence_length)))
return sequences
print(get_sequences(my_list, 2))
print(get_sequences(my_list, 3))
will output
['12', '23', '34', '45', '56', '67', '78', '89', '91']
['123', '234', '345', '456', '567', '678', '789', '891', '912']
This is nice because it utilizes a generator everywhere that it can.
This could give ideas. The only thing to check is the order in your interval. Works with any n.
array = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']
def print_neighbors(n_neighbors):
for idx in range(len(array)):
start = (idx- n_neighbors//2) % len(array)
end = (idx+n_neighbors//2) % len(array) + 1
if start > end:
print(''.join(array[start:] + array[:end]))
else:
print(''.join(array[start:end]))
>>> print_neighbors(6)
ijkabcd
jkabcde
kabcdef
abcdefg
bcdefgh
cdefghi
defghij
efghijk
fghijka
ghijkab
hijkabc
You could create a class to wrap your original iterable like this:
class WrappingIterable():
def __init__(self, orig):
self.orig=orig
def __getitem__(self, index):
return self.orig[index%len(self.orig)]
def __len__(self):
return len(self.orig)
>>> w = WrappingIterable("qwerty")
>>> for i in range(-2, 8):
... print(w[i])
t
y
q
w
e
r
t
y
q
w
For this particular issue you can use a snippet like this:
def print_neighbors(l, n):
wrapped = l[-(n//2):] + l + l[:(n//2)]
for i in range(len(l)):
print(''.join(wrapped[i:i+n+1]))
l = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']
print_neighbors(l, 2)
print_neighbors(l, 4)
Hope it makes sense!
I have a list a = ["c","o","m","p","a","r","e"]. I have two lists
b = ["c","l","o","m","p","a","r","e"] and c=["c","o","m","p","a","e","r"]
now i want to compare list 'b' and 'c' with 'a' to see whether the order of elements of 'b' are closer to 'a' or order of elements of 'c' are closer to and return the list. What I would like to achieve is list 'b' is to be returned when comparing 'b' and 'c' with 'a'. Is there a function to do that?
difflib.SequenceMatcher will find
the longest contiguous matching subsequence
that contains no "junk" elements
SequenceMatcher.ratio returns the measure of the sequences' similarity. It's a float in the range [0, 1]. Higher ratio indicates higher similarity (the ratio is 1 if given sequences are identical).
The below helper function uses the max function to compare the first argument to the rest of positional arguments:
def closest(seq, *args):
# Cache information about `seq`.
# We only really need to change one sequence.
sm = SequenceMatcher(b=seq)
def _ratio(x):
sm.set_seq1(x)
return sm.ratio()
return max(args, key=_ratio)
Example:
In [37]: closest(
....: ['c', 'o', 'm', 'p', 'a', 'r', 'e'], # a
....: ['c', 'l', 'o', 'm', 'p', 'a', 'r', 'e'], # b
....: ['c', 'o', 'm', 'p', 'a', 'e', 'r'] # c
....: )
Out[37]: ['c', 'l', 'o', 'm', 'p', 'a', 'r', 'e'] # b
The traditional way of solving this problem is by using Levenshtein distance. This basically tallies up all of the additions, deletions and insertions required to move from one string to another.
You can think of each of those operations as "breaking" the pattern of a just a bit.
It's a pretty simple function to implement, but there's a package that has already done it for you here. Sample code is below:
>>> from Levenshtein import distance
>>> distance("compare", "clompare")
1
>>> distance("compare", "compaer")
2