Use list to generate lowercase letter and number in python - list

I am trying to use a list such as:
[(1,4),(2,2)]
To get:
[(a,4),(b,2)]
I am trying to use 'string.ascii_lowercase' how would I accomplish this in Python3, this is for a coding challenge to get the least characters possible.
Thanks for any help!

I'm not going to solve it for you, but I'd suggest you look into the chr and ord functions. Note that the ASCII code for "a" is 97, so to convert 1 to "a" you would have to add 96 to it.

I would suggest you to follow the suggestion given by B.Eckles above as you would learn better and probably find a shorter (character-wise) solution.
However, if you want to stick with using string.ascii_lowercase, the code snippet below could be useful to start from:
import string
a = [(1,4),(2,2)]
b = []
for (first, second) in a:
b.append(
(string.ascii_lowercase[(first-1) % len(string.ascii_lowercase)],
second))
print b
In this case, the printed solution would be:
[('a', 4), ('b', 2)]
I have inserted the module (i.e. % len(string.ascii_lowercase)) to avoid out-of-bound accesses. Just be careful that the value 0 would produce 'z' in this way.
Hope it helps!

Related

Exact match of string in pandas python

I have a column in data frame which ex df:
A
0 Good to 1. Good communication EI : tathagata.kar#ae.com
1 SAP ECC Project System EI: ram.vaddadi#ae.com
2 EI : ravikumar.swarna Role:SSE Minimum Skill
I have a list of of strings
ls=['tathagata.kar#ae.com','a.kar#ae.com']
Now if i want to filter out
for i in range(len(ls)):
df1=df[df['A'].str.contains(ls[i])
if len(df1.columns!=0):
print ls[i]
I get the output
tathagata.kar#ae.com
a.kar#ae.com
But I need only tathagata.kar#ae.com
How Can It be achieved?
As you can see I've tried str.contains But I need something for extact match
You could simply use ==
string_a == string_b
It should return True if the two strings are equal. But this does not solve your issue.
Edit 2: You should use len(df1.index) instead of len(df1.columns). Indeed, len(df1.columns) will give you the number of columns, and not the number of rows.
Edit 3: After reading your second post, I've understood your problem. The solution you propose could lead to some errors.
For instance, if you have:
ls=['tathagata.kar#ae.com','a.kar#ae.com', 'tathagata.kar#ae.co']
the first and the third element will match str.contains(r'(?:\s|^|Ei:|EI:|EI-)'+ls[i])
And this is an unwanted behaviour.
You could add a check on the end of the string: str.contains(r'(?:\s|^|Ei:|EI:|EI-)'+ls[i]+r'(?:\s|$)')
Like this:
for i in range(len(ls)):
df1 = df[df['A'].str.contains(r'(?:\s|^|Ei:|EI:|EI-)'+ls[i]+r'(?:\s|$)')]
if len(df1.index != 0):
print (ls[i])
(Remove parenthesis in the "print" if you use python 2.7)
Thanks for the help. But seems like I found a solution that is working as of now.
Must use str.contains(r'(?:\s|^|Ei:|EI:|EI-)'+ls[i])
This seems to solve the problem.
Although thanks to #IsaacDj for his help.
Why not just use:
df1 = df[df['A'].[str.match][1](ls[i])
It's the equivalent of regex match.

How do I transform this code into a list comprehension?

I have this code in Python2.7 and I wanna (if possible) transform this code into a list comprehension.
z=[]
if p==1:
z.append('a')
if m==2:
z.append('b')
print ''.join(z)
The problem is it gives me an error (syntax error) when I transformed the code like this:
z=['b' if m==2 'a' if p==1]
print ''.join(z)
Or
z=['a' if p==1 'b' if ==m]
print ''.join(z)
Please let me know if this question has a duplicate.
I would appreciate your advice.
This is a tricky one. I came up with a solution that uses enumerate and an inline if statement to tell the difference between the two if statements. Honestly, using a list comp for this will probably obfuscate the code and it'd be better to just stick with the simpler if statements you already have.
values = ['a', 'b'] # put the append arguments in here, you can also inline this but I put it apart to make the line shorter
z = [val for idx, val in enumerate(values) if (m==2 and p==1 if idx==1 else p==1)]

Printing Values from a list without spaces in python 2.7

Suppose I have a list like
list1 = ['A','B','1','2']
When i print it out I want the output as
AB12
And not
A B 1 2
So far I have tried
(a)print list1,
(b)for i in list1:
print i,
(c)for i in list1:
print "%s", %i
But none seem to work.
Can anyone suggest an alternate method
Thank you.
From your comments on #jftuga answer, I guess that the input you provided is not the one you're testing with. You have mixed contents in your list.
My answer will fix it for you:
lst = ['A','B',1,2]
print("".join([str(x) for x in lst]))
or
print("".join(map(str,lst)))
I'm not just joining the items since not all of them are strings, but I'm converting them to strings first, all in a nice generator comprehension which causes no memory overhead.
Works for lists with only strings in them too of course (there's no overhead to convert to str if already a str, even if I believed otherwise on my first version of that answer: Should I avoid converting to a string if a value is already a string?)
Try this:
a = "".join(list1)
print(a)
This will give you: AB12
Also, since list is a built-in Python class, do not use it as a variable name.

Testing for an item in lists - Python 3

As part of a school project we are creating a trouble shooting program. I have come across a problem that I cannot solve:
begin=['physical','Physical','Software','software',]
answer=input()
if answer in begin[2:3]:
print("k")
software()
if answer in begin[0:1]:
print("hmm")
physical()
When I try to input software/Software no output is created. Can anybody see a hole in my code as it is?
In Python, slice end values are exclusive. You are slicing a smaller list than you think you are:
>>> begin=['physical','Physical','Software','software',]
>>> begin[2:3]
['Software']
>>> begin[0:1]
['physical']
Use begin[2:4] and begin[0:2] or even begin[2:] and begin[:2] to get all elements from the 3rd to the end, and from the start until the 2nd (inclusive):
>>> begin[2:]
['Software', 'software']
>>> begin[2:4]
['Software', 'software']
>>> begin[:2]
['physical', 'Physical']
>>> begin[0:2]
['physical', 'Physical']
Better yet, use str.lower() to limit the number of inputs you need to provide:
if answer.lower() == 'software':
With only one string to test, you can now put your functions in a dictionary; this gives you the option to list the various valid answers too:
options = {'software': software, 'physical': physical}
while True:
answer = input('Please enter one of the following options: {}\n'.format(
', '.join(options))
answer = answer.lower()
if answer in options:
options[answer]()
break
else:
print("Sorry, {} is not a valid option, try again".format(answer))
Your list slicing is wrong, Try the following script.
begin=['physical','Physical','Software','software',]
answer=input()
if answer in begin[2:4]:
print("k")
software()
if answer in begin[0:2]:
print("hmm")
physical()

Regex to find words with one character diff

I have a word dictionary and I'm looking for regex that can help me to get words with only one character diff. For example say for word BIG it could be words BIT, BUG etc. Length of the words should be equal.
Thank you!
/\b([a-z]ig|b[a-z]g|bi[a-z])\b/i
You'd have to do this with every word. Regex alone is probably not the best tool for this job.
Use something like this, perhaps?
>>> def word_difference(word1, word2):
... c1, c2 = list(word1), list(word2)
... return [(i, c1[i], c2[i]) for i in in range(len(c1)) if c1[i] != c2[i]]
>>> word_difference("foo", "bar")
[(0, 'f', 'b'), (1, 'o', 'a'), (2, 'o', 'r')]
>>> word_difference("big", "bug")
[(1, 'i', 'u')]
Obviously, the length of the list returned is the number of characters that are different. I assume this is what you want, since you didn't state whether the characters may be in different positions or not - but that's just as easy, you can use sets.
I found nearly the same solution than the one using ideone.
But, as vkolodrevskiy wrote “to get words with only one character diff“,
I respected it.
My code is in Python. No language precised in the question.
import re
word = 'main'
RE = '|'.join(word[0:i]+'(?!'+char+')[a-z]'+word[i+1:] for i,char in enumerate(word))
RE = '('+RE+')'
print RE
ch = 'the main reason is pain due to rain. hello muin, where is maih ?'
print re.findall(RE,ch)
Well, you could do a bunch of complicated regular expressions, or ingenius ones, but I found something that I wanted to tell you about that may be a lot easier.
Check out the Levenshtein module to get the hamming distance between two strings. Then just get the ones that have a distance of one.
To install you can use pip install python-levenshtein. If you use Ubuntu or such you can use sudo apt-get install python-levenshtein. If you're on Windows, in order to fully utilize pip you'll need a C++ compiler (like Visual C++ 2010 express, if you're using Python 3, or Visual C++ 2008 express for Python 2.x; you can download those for free from Microsoft; do a web search for them if you want them).
import Levenshtein #Note the capital L
help(Levenshtein) #See the documentation
Levenshtein.hamming("cat", "sat") #Returns 1; they must be the same length, as you specified
There are lots of other cool functions besides hamming, though. Read the help (via the help function in the code above). The functions are actually surprisingly well-documented if you use the help function. Press q to quit the help, of course.
finally I did not use idea with regex, my solution looks like:
public boolean diffOneChar(String word1, String word2) {
int diff=0;
if(word1 == null || word2 == null) return false;
if(word1.length() == 0 || word2.length() == 0) return false;
if(word1.length() != word2.length()) return false;
for(int i=0; i<word1.length(); i++) {
if(word1.charAt(i)!=word2.charAt(i))
diff++;
}
return diff == 1;
}