Trying to verify last position of a string - python

Im trying to verify if the last char is not on my list
def acabar_char(input):
list_chars = "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 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 6 7 8 9 0".split()
tam = 0
tam = (len(input)-1)
for char in input:
if char[tam] in list_chars:
return False
else:
return True
When i try this i get this error:
if char[tam] in list_chars:
IndexError: string index out of range

you can index from the end (of a sting or a list) with negative numbers
def acabar_char(input, list_cars):
return input[-1] is not in list_chars

It seems that you are trying to assert that the last element of an input string (or also list/tuple) is NOT in a subset of disallowed chars.
Currently, your loop never even gets to the second and more iteration because you use return inside the loop; so the last element of the input only gets checked if the input has length of 1.
I suggest something like this instead (also using the string.ascii_letters definition):
import string
DISALLOWED_CHARS = string.ascii_letters + string.digits
def acabar_char(val, disallowed_chars=DISALLOWED_CHARS):
if len(val) == 0:
return False
return val[-1] not in disallowed_chars
Does this work for you?

you are already iterating through your list in that for loop, so theres no need to use indices. you can use list comprehension as the other answer suggest, but I'm guessing you're trying to learn python, so here would be the way to rewrite your function.
list_chars = "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 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 6 7 8 9 0".split()
for char in input:
if char in list_chars:
return False
return True

list_chars = "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 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 6 7 8 9 0".split()
def acabar_char(input):
if input in list_chars:
print('True')

Related

Alphabetical Grid using python3

how to write a function grid that returns an alphabetical grid of size NxN, where a = 0, b = 1, c = 2.... in python
example :
a b c d
b c d e
c d e f
d e f g
here I try to create a script using 3 for loops but it's going to print all the alphabets
def grid(N):
for i in range(N):
for j in range(N):
for k in range(ord('a'),ord('z')+1):
print(chr(k))
pass
Not the most elegant, but gets the job done.
import string
def grid(N):
i = 0
for x in range(N):
for y in string.ascii_lowercase[i:N+i]:
print(y, end=" ")
i += 1
print()
grid(4)
Output
a b c d
b c d e
c d e f
d e f g
Extending from #MichHeng's suggestion, and using list comprehension:
letters = [chr(x) for x in range(ord('a'),ord('z')+1)]
def grid(N):
for i in range(N):
print(' '.join([letters[i] for i in range(i,N+i)]))
grid(4)
output is
a b c d
b c d e
c d e f
d e f g
You have specified for k in range(ord('a'),ord('z')+1) which prints out the entire series from 'a' to 'z'. What you probably need is a reference list comprehension to pick your letters from, for example
[chr(x) for x in range(ord('a'),ord('z')+1)]
Try this:
letters = [chr(x) for x in range(ord('a'),ord('z')+1)]
def grid(N):
for i in range(N):
for j in range(i, N+i):
print(letters[j], end=' ')
if j==N+i-1:
print('') #to move to next line
grid(4)
Output
a b c d
b c d e
c d e f
d e f g
Do you need to add a check for N<=13 ?

How do you remove the whitespace in a string with multiple lines python?

i use python to read a txt file.
i have tried using .lstrip to remove the whitespace from the left but it only manages to remove the whitespace from the first line.
In the text file:
when i use this:
puzzle = puzzle.replace('',' ')
x m f y c x v t l j l q b b y b k o u m j q w b t
c a u b m e k n b e y d q m c n z y j p v r a n k
a q a c t i v e x n y v w d v c o s h o y a o h g
p a g h z k c t u d p t j d p h s z t p r h t t l
s b s n a k j w q b o u f t m g n j q b t l i n u
t s e w o h v o b d s d u q j i f f k y y l o d o
o u k w w e f r o y a m a p m l r r p v d o l o p
c q k f x t l k s j v t m t r s b y c m q r r r i
k f e r v l q i d q a x a o a n f q j l m c p j h
y o y y w r b p f c j l f b c b b c o e c s p w l
t w b x e t y u y u f v v m a u a w j m b w l q h
t x o k d e x m d b t g v h p s v s q t m l j d x
d c a t e n r e h t e o x q d g e u e l j t r r n
j a r t e q v t x e j f s q d d k b u h c y s f q
h p d r o w s s a p x t r x h p d x c d h i c o n
what i get when i use: print (puzzle.lstrip())
x m f y c x v t l j l q b b y b k o u m j q w b t
c a u b m e k n b e y d q m c n z y j p v r a n k
a q a c t i v e x n y v w d v c o s h o y a t j d p h s z t p r h t t l
s b s n a k j w q b o u f t m g n j q b t l i n u
t s e w o h v o b d s d u q j i f f k y y l o d o
o u k w w e f r o y a m a p m l r r p v d o l o p
c q k f x t l k s j v t m t r s b y c m q r r r i
k f e r v l q i d q a x a o a n f q j l m c p j h
y o y y w r b p f c j l f b c b b c o e c s p w l
t w b x e t y u y u f v v m a u a w j m b w l q h
t x o k d e x m d b t g v h p s v s q t m l j d x
d c a t e n r e h t e o x q d g e u e l j t r r n
j a r t e q v t x e j f s q d d k b u h c y s f q
h p d r o w s s a p x t r x h p d x c d h i c o n
Instead i want remove all the whitespace from the left to get:
x m f y c x v t l j l q b b y b k o u m j q w b t
c a u b m e k n b e y d q m c n z y j p v r a n k
a q a c t i v e x n y v w d v c o s h o y a o h g
p a g h z k c t u d p t j d p h s z t p r h t t l
s b s n a k j w q b o u f t m g n j q b t l i n u
t s e w o h v o b d s d u q j i f f k y y l o d o
o u k w w e f r o y a m a p m l r r p v d o l o p
c q k f x t l k s j v t m t r s b y c m q r r r i
k f e r v l q i d q a x a o a n f q j l m c p j h
y o y y w r b p f c j l f b c b b c o e c s p w l
t w b x e t y u y u f v v m a u a w j m b w l q h
t x o k d e x m d b t g v h p s
Thanks for your help!!!!
Starting from txt
txt = """xmfycxvtljlqbbybkoumjqwbt
caubmeknbeydqmcnzyjpvrank
aqactivexnyvwdvcoshoyaohg
paghzkctudptjdphsztprhttl
sbsnakjwqbouftmgnjqbtlinu
tsewohvobdsduqjiffkyylodo
oukwwefroyamapmlrrpvdolop
cqkfxtlksjvtmtrsbycmqrrri
kfervlqidqaxaoanfqjlmcpjh
yoyywrbpfcjlfbcbbcoecspwl
twbxetyuyufvvmauawjmbwlqh
txokdexmdbtgvhpsvsqtmljdx
dcatenrehteoxqdgeueljtrrn
jarteqvtxejfsqddkbuhcysfq
hpdrowssapxtrxhpdxcdhicon"""
you can print the desired result like that:
for line in txt.splitlines():
print(' '.join(line))
and if you don't want to print, you can use a list comprehension to store the results in a variable:
result = [' '.join(line) for line in txt.splitlines()]
You can replace all instances of newline followed by space by newline:
puzzle = puzzle.replace('\n ','')
I suppose this might work:
result = [row.lstrip() for row in filehandle.readlines()]

How to create data frame from pandas series containg lists of different length

I've got pandas series withe below structure:
> 0 [{k1:a,k2:b,k3:c},{k1:d,k2:e,k3:f}]
> 1 [{k1:g,k2:h,k3:i},{k1:j,k2:k,k3:l},{k1:ł,k2:m,k3:n}]
> 2 [{k1:o,k2:p,k3:r}
> 3 [{k1:s,k2:t,k3:w},{k1:q,k2:z,k3:w},{k1:x,k2:y,k3:z},{k1:v,k2:f,k3:g}]
As You can see this series contains elemnts as lists of different length. Elements in each list are dictionaries. I would like to create data frame, which will looks like that:
> k1 k2 k3
> 0 a b c
> 1 d e f
> 2 g h i
> 3 j k l
> 4 ł m n
> 5 o p r
> 6 s t w
> 7 q z w
> 8 x y z
> 9 f v g
I have tried below code:
>for index_val, series_val in series.iteritems():
>> for dict in series_val:
>>> for key,value in dict.items():
>>>> actions['key']=value
However PyCharm stops and produces nothing. Are there any other method to do that?
Use concat with apply pd.DataFrame i.e
x = pd.Series([[{'k1':'a','k2':'b','k3':'c'},{'k1':'d','k2':'e','k3':'f'}], [{'k1':'g','k2':'h','k3':'i'},{'k1':'j','k2':'k','k3':'l'},{'k1':'ł','k2':'m','k3':'n'}],
[{'k1':'o','k2':'p','k3':'r'}],[{'k1':'s','k2':'t','k3':'w'},{'k1':'q','k2':'z','k3':'w'},{'k1':'x','k2':'y','k3':'z'},{'k1':'v','k2':'f','k3':'g'}]])
df = pd.concat(x.apply(pd.DataFrame,1).tolist(),ignore_index=True)
Output :
k1 k2 k3
0 a b c
1 d e f
2 g h i
3 j k l
4 ł m n
5 o p r
6 s t w
7 q z w
8 x y z
9 v f g

Optimizing pandas filter inside apply function

I have a list of pairs--stored in a DataFrame--each pair having an 'a' column and a 'b' column. For each pair I want to return the 'b's that have the same 'a'. For example, given the following set of pairs:
a b
0 c d
1 e f
2 c g
3 e h
4 i j
5 e k
I would like to end up with:
a b equivalents
0 c d [g]
1 e f [h, k]
2 c g [d]
3 e h [f, k]
4 i j []
5 e k [h, e]
I can do this with the following:
def equivalents(x):
l = pairs[pairs["a"] == x["a"]]["b"].tolist()
return l[1:] if l else l
pairs["equivalents"] = pairs.apply(equivalents, axis = 1)
But it is painfully slow on larger sets (e.g. 1 million plus pairs). Any suggestions how I could do this faster?
I think this ought to be a bit faster. First, just add them up.
df['equiv'] = df.groupby('a')['b'].transform(sum)
a b equiv
0 c d dg
1 e f fhk
2 c g dg
3 e h fhk
4 i j j
5 e k fhk
Now convert to a list and remove whichever letter is already in column 'b'.
df.apply( lambda x: [ y for y in list( x.equiv ) if y != x.b ], axis=1 )
0 [g]
1 [h, k]
2 [d]
3 [f, k]
4 []
5 [f, h]

Creating a file of a specific size with incrementing alphabets/numbers in python.

How to create a file of a specific size (say 1024bytes) and each line should have a number or alphabet in an incrementing order. The total size of the file should not exceed 1024 bytes(even after putting alphabets/numbers in it).
I tried this
def create_file_numbers(filename, size):
f=open(filename,"wb")
for x in range(size):
f.write(str(x))
f.write('\r\n')
f.close()
pass
But this creates a file of size much greater than 1024 having numbers 1 to 1023.I am a beginner in python so explanation would be appreciated.
A string representation of a number is larger than just the number, typically one, two, or four bytes for each character. Your \r and \n take up that space too.
max_len = max_size / bytes_per_char
s = ''
i = 0
while len(s) < max_len:
s += str(i) + '\r\n'
i += 1
if len(s) > max_len: # because it may not divide evenly
s = s[:max_len]
open(filename, "wb").write(s)
Define your string of characters:
import string
alphabet = string.digits + string.ascii_letters
Then replace:
f.write(str(x))
with:
f.write(alphabet[x % len(alphabet)])
For example:
>>> import string
>>> alphabet = string.digits + string.ascii_letters
>>> ' '.join(alphabet[x % len(alphabet)] for x in range(200))
'0 1 2 3 4 5 6 7 8 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 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 0 1 2 3 4 5 6 7 8 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 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 0 1 2 3 4 5 6 7 8 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 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 0 1 2 3 4 5 6 7 8 9 a b c d'
The only tricky thing about this is that numbers have increasing numbers of digits as they get larger. You can avoid that by padding with zeroes to make each line the same size. For example, let's make each line 8 bytes long. The '\r\n' takes up two, leaving 6 for the digits, and that's more than enough.
for n in range(1024/8):
f.write('%06d\r\n' % n)
To get exactly 1024 bytes without padding, you won't be able to start at 0 or 1. A line with a single digit takes three bytes, two digits takes four bytes, and three digits takes five. 1024 / 5 = 204 remainder 4, so you want 204 lines with three-digit numbers and one with a two-digit number. The two-digit number has to be 99 so that the next number will have three digits. So this works:
for n in range(99, 304):
f.write('%d\r\n' % n)

Categories