How can I do 'a' + 1 #=> 'b' in python? - python

I'm working on a project need this functionality very frequently
'b' + 1 #=> 'a' and 'b' - 1 #=> 'a'
Now my solution is very tedious :
str(unichr((ord('b')+ 1)))
is there a more elegant way to do this?

str(unichr(c)) can be replaced with just chr(c).
Simplified version:
chr(ord('b') + 1)

define your own function:
In [103]: def func(c,n):
return chr(ord(c)+n)
.....:
In [105]: func('a',-1)
Out[105]: '`'
In [106]: func('b',-1)
Out[106]: 'a'
In [107]: func('c',2)
Out[107]: 'e'

Python is strongly typed and considerer strings and ints are different, and won't convert one to another implicitly.
However, you code can probably be simplified to
chr(ord('b') + 1)
If you use it a lot, put it in a function, and don't worry about it any more :
def incr_char(c, n):
return chr(ord(c) + n)

Try this instead:
>>> import string
>>> string.letters[string.letters.index('a')+1]
'b'
Just for Ashwini:
>>> string.letters[string.letters.index('a')-1]
'Z'

You can do something like:
class char(unicode):
def __add__(self, x):
return char(unichr(ord(self) + x))
print char('a') + 1 # b

Related

counting occurance of an alphabet in a list

I am writing a code in python to count number of times an alphabet occurs in a given sequence using list comprehension
For example:
countoccur("s", "ssssdfrtsgjdt" )
should give 5 as output since s occurs five times. I wrote this code and get the following output:
def countoccur(x,s):
y=[e for e in s if e==x]
return y
output:
['s', 's', 's', 's', 's']
can someone help me fix this?
Python has better tools but if you want to keep your code, Just return the len of y:
def countoccur(x,s):
y=[e for e in s if e==x]
return len(y)
Outout:
output: 5
You can also use count():
print string.count('s')
or findall():
print len(re.findall("s", string))
Python really comes with all the batteries included, try using collections.Counter
In [1]: from collections import Counter
In [2]: s="ssssdfrtsgjdt"
In [3]: Counter(s)
Out[3]: Counter({'s': 5, 'd': 2, 't': 2, 'g': 1, 'f': 1, 'j': 1, 'r': 1})
In [4]: Counter(s)['s']
Out[4]: 5
You can simply use the builtin str.count function, like this
def countoccur(char, input_string):
return input_string.count(char)
print countoccur("s", "ssssdfrtsgjdt" )
I would suggest using a generator expression and sum function like this
return sum(1 for e in input_string if e == char)
This can be shortened to the following, as #volcano suggested in the comments
return sum(e == char for e in input_string)
This works because, in Python, True == 1 and False == 0 :)
If you want to use only comprehension,
return sum([e == char for e in input_string])
To write a Counter manually as Fredrik Pihl mentioned:
In [60]: from collections import defaultdict
...: cnt=defaultdict(int)
...: s="ssssdfrtsgjdt"
...: for v in s:
...: cnt[v]+=1
...:
In [61]: print cnt['s'], cnt['d']
5 2

Python Concatenating Strings

1 def add(i):
2 return '\''+i+'\''
3 a = ['a', 'b']
4 print " or ".join([add(i) for i in a])
OUTPUT: 'a' or 'b'
I am not sure if the above is the best way (esp the add function).
Is there a better way to achieve what I am trying to do?
You can use repr:
>>> a = ['a', 'b']
>>> print " or ".join(repr(i) for i in a)
'a' or 'b'

Python - Make sure string is converted to correct Float

I have possible strings of prices like:
20.99, 20, 20.12
Sometimes the string could be sent to me wrongly by the user to something like this:
20.99.0, 20.0.0
These should be converted back to :
20.99, 20
So basically removing anything from the 2nd . if there is one.
Just to be clear, they would be alone, one at a time, so just one price in one string
Any nice one liner ideas?
For a one-liner, you can use .split() and .join():
>>> '.'.join('20.99.0'.split('.')[:2])
'20.99'
>>> '.'.join('20.99.1231.23'.split('.')[:2])
'20.99'
>>> '.'.join('20.99'.split('.')[:2])
'20.99'
>>> '.'.join('20'.split('.')[:2])
'20'
You could do something like this
>>> s = '20.99.0, 20.0.0'
>>> s.split(',')
['20.99.0', ' 20.0.0']
>>> map(lambda x: x[:x.find('.',x.find('.')+1)], s.split(','))
['20.99', ' 20.0']
Look at the inner expression of find. I am finding the first '.' and incrementing by 1 and then find the next '.' and leaving everything from that in the string slice operation.
Edit: Note that this solution will not discard everything from the second decimal point, but discard only the second point and keep additional digits. If you want to discard all digits, you could use e.g. #Blender's solution
It only qualifies as a one-liner if two instructions per line with a ; count, but here's what I came up with:
>>> x = "20.99.1234"
>>> s = x.split("."); x = s[0] + "." + "".join(s[1:])
>>> x
20.991234
It should be a little faster than scanning through the string multiple times, though. For a performance cost, you can do this:
>>> x = x.split(".")[0] + "." + "".join(x.split(".")[1:])
For a whole list:
>>> def numify(x):
>>> s = x.split(".")
>>> return float( s[0] + "." + "".join(s[1:]))
>>> x = ["123.4.56", "12.34", "12345.6.7.8.9"]
>>> [ numify(f) for f in x ]
[123.456, 12.34, 12345.6789]
>>> s = '20.99, 20, 20.99.23'
>>> ','.join(x if x.count('.') in [1,0] else x[:x.rfind('.')] for x in s.split(','))
'20.99, 20, 20.99'
If you are looking for a regex based solution and your intended behaviour is to discard everthing after the second .(decimal) than
>>> st = "20.99.123"
>>> string_decimal = re.findall(r'\d+\.\d+',st)
>>> float(''.join(string_decimal))
20.99

Python findall in a string

There must be an easier way or function to do this code here:
#!/usr/bin/env python
string = "test [*string*] test [*st[ *ring*] test"
points = []
result = string.find("[*")
new_string = string[result+1:]
while result != -1:
points.append(result)
new_string = new_string[result+1:]
result = new_string.find("[*")
print points
Any ideas?
import re
string = "test [*string*] test [*st[ *ring*] test"
points = [m.start() for m in re.finditer('\[', string)]
It looks like you're trying to get the indices in the string that match '[*'...
indices=[i for i in range(len(string)-1) if string[i:i+2] == '[*']
But this output is different than what your code will produce. Can you verify that your code does what you want?
Also note that string is the name of a python module in the standard library -- while it isn't used very often, it's probably a good idea to avoid using it as a variable name. (don't use str either)
>>> indexes = lambda str_, pattern: reduce(
... lambda acc, x: acc + [acc[-1] + len(x) + len(pattern)],
... str_.split(pattern), [-len(pattern)])[1:-1]
>>> indexes('123(456(', '(')
[3, 7]
>>> indexes('', 'x')
[]
>>> indexes("test [*string*] test [*st[ *ring*] test", '[*')
[5, 21]
>>> indexes('1231231','1')
[0, 3, 6]

Iterative find/replace from a list of tuples in Python

I have a list of tuples, each containing a find/replace value that I would like to apply to a string. What would be the most efficient way to do so? I will be applying this iteratively, so performance is my biggest concern.
More concretely, what would the innards of processThis() look like?
x = 'find1, find2, find3'
y = [('find1', 'replace1'), ('find2', 'replace2'), ('find3', 'replace3')]
def processThis(str,lst):
# Do something here
return something
>>> processThis(x,y)
'replace1, replace2, replace3'
Thanks, all!
You could consider using re.sub:
import re
REPLACEMENTS = dict([('find1', 'replace1'),
('find2', 'replace2'),
('find3', 'replace3')])
def replacer(m):
return REPLACEMENTS[m.group(0)]
x = 'find1, find2, find3'
r = re.compile('|'.join(REPLACEMENTS.keys()))
print r.sub(replacer, x)
A couple notes:
The boilerplate argument about premature optimization, benchmarking, bottlenecks, 100 is small, etc.
There are cases where the different solutions will return different results. if y = [('one', 'two'), ('two', 'three')] and x = 'one' then mhawke's solution gives you 'two' and Unknown's gives 'three'.
Testing this out in a silly contrived example mhawke's solution was a tiny bit faster. It should be easy to try it with your data though.
x = 'find1, find2, find3'
y = [('find1', 'replace1'), ('find2', 'replace2'), ('find3', 'replace3')]
def processThis(str,lst):
for find, replace in lst:
str = str.replace(find, replace)
return str
>>> processThis(x,y)
'replace1, replace2, replace3'
s = reduce(lambda x, repl: str.replace(x, *repl), lst, s)
Same answer as mhawke, enclosed with method str_replace
def str_replace(data, search_n_replace_dict):
import re
REPLACEMENTS = search_n_replace_dict
def replacer(m):
return REPLACEMENTS[m.group(0)]
r = re.compile('|'.join(REPLACEMENTS.keys()))
return r.sub(replacer, data)
Then we can call this method with example as below
s = "abcd abcd efgh efgh;;;;;; lkmnkd kkkkk"
d = dict({ 'abcd' : 'aaaa', 'efgh' : 'eeee', 'mnkd' : 'mmmm' })
print (s)
print ("\n")
print(str_replace(s, d))
output :
abcd abcd efgh efgh;;;;;; lkmnkd kkkkk
aaaa aaaa eeee eeee;;;;;; lkmmmm kkkkk

Categories

Resources