How to downcase the first character of a string? - python

There is a function to capitalize a string, I would like to be able to change the first character of a string to be sure it will be lowercase.
How can I do that in Python?

One-liner which handles empty strings and None:
func = lambda s: s[:1].lower() + s[1:] if s else ''
>>> func(None)
>>> ''
>>> func('')
>>> ''
>>> func('MARTINEAU')
>>> 'mARTINEAU'

s = "Bobby tables"
s = s[0].lower() + s[1:]

def first_lower(s):
if len(s) == 0:
return s
else:
return s[0].lower() + s[1:]
print first_lower("HELLO") # Prints "hELLO"
print first_lower("") # Doesn't crash :-)

Interestingly, none of these answers does exactly the opposite of capitalize(). For example, capitalize('abC') returns Abc rather than AbC. If you want the opposite of capitalize(), you need something like:
def uncapitalize(s):
if len(s) > 0:
s = s[0].lower() + s[1:].upper()
return s

Simplest way:
>>> mystring = 'ABCDE'
>>> mystring[0].lower() + mystring[1:]
'aBCDE'
>>>
Update
See this answer (by #RichieHindle) for a more foolproof solution, including handling empty strings. That answer doesn't handle None though, so here is my take:
>>> def first_lower(s):
if not s: # Added to handle case where s == None
return
else:
return s[0].lower() + s[1:]
>>> first_lower(None)
>>> first_lower("HELLO")
'hELLO'
>>> first_lower("")
>>>

No need to handle special cases (and I think the symmetry is more Pythonic):
def uncapitalize(s):
return s[:1].lower() + s[1:].upper()

I'd write it this way:
def first_lower(s):
if s == "":
return s
return s[0].lower() + s[1:]
This has the (relative) merit that it will throw an error if you inadvertently pass it something that isn't a string, like None or an empty list.

This duplicate post lead me here.
If you've a list of strings like the one shown below
l = ['SentMessage', 'DeliverySucceeded', 'DeliveryFailed']
Then, to convert the first letter of all items in the list, you can use
l = [x[0].lower() + x[1:] for x in l]
Output
['sentMessage', 'deliverySucceeded', 'deliveryFailed']

pip install pydash first.
import pydash # pip install pydash
assert pydash.lower_first("WriteLine") == "writeLine"
https://github.com/dgilland/pydash
https://pydash.readthedocs.io/en/latest/
https://pypi.org/project/pydash/

Related

Why I can't delete everything except for certain characters using a loop

I have a code
def printer_error(s):
allowed = "abcdefghijklm"
return [s.replace(x, "") for x in allowed if x in s]
print(printer_error("xyzabcdef"))
That is what code must returns:
"abcdef"
And that is what code returns really:
['xyzbcdef', 'xyzacdef', 'xyzabdef', 'xyzabcef', 'xyzabcdf', 'xyzabcde']
I think that the problem is on line 3, but idk what`s wrong
Try this:
def printer_error(s):
allowed = "abcdefghijklm"
for x in s:
if x not in allowed:
s = s.replace(x, "")
return s
print(printer_error("xyzabcdef"))
Its because you're using a list comprehension, instead you just have to have that replace function, like this...
def printer_error(s):
allowed = "abcdefghijklm"
for char in s:
if char not in allowed:
s = s.replace(char, "")
return s
print(printer_error("xyzabcdef"))

Rotating strings in Python

I was trying to make the string HELLO to OHELL in Python. But couldn't get any way to rotate it without working with loops. How to code for it in just 1-2 lines so that I could get the desired pattern?
Here is one way:
def rotate(strg, n):
return strg[n:] + strg[:n]
rotate('HELLO', -1) # 'OHELL'
Alternatively, collections.deque ("double-ended queue") is optimised for queue-related operations. It has a dedicated rotate() method:
from collections import deque
items = deque('HELLO')
items.rotate(1)
''.join(items) # 'OHELL'
You can slice and add strings:
>>> s = 'HELLO'
>>> s[-1] + s[:-1]
'OHELL'
This gives you the last character:
>>> s[-1]
'O'
and this everything but the last:
>>> s[:-1]
'HELL'
Finally, add them with +.
Here is what I use to rotate strings in Python3:
To rotate left by n:
def leftShift(text,n):
return text[n:] + text[:n]
To rotate right by n:
def rightShift(text,n):
return text[-n:] + text[:-n]
Here is a simple way of looking at it...
s = 'HELLO'
for r in range(5):
print(s[r:] + s[:r])
HELLO
ELLOH
LLOHE
LOHEL
OHELL
I would agree with Mike Müller's answer:
s = 'HELLO'
s = s[-1] + s[:-1]
I would like to share another way of looking at s[:-1]
s[0:-1]
This means that it is starting from the start and including everything except for s[-1].
I hope this helped.

How do I replace all instances of the first letter in a string, but not the first letter itself

My code so far is:
def ChangeString():
print (userString.replace(
userString =str(input("Please enter a string "))
ChangeString()
In a string, I need to replace all instances of the first character with a *, without actually replacing the first character itself. An example is, let's say I have "Bobble"; the function would return something like, "Bo**le".
userString[0] + userString[1:].replace(userString[0], "*")
>>> test = 'Bobble'
>>> test = test[0] +''.join(l if l.lower() != test[0].lower() else '*' for l in test[1:])
>>> print test
Bo**le
You could also use a regex:
import re
def ign_first(s, repl):
return re.sub(r"(?<!^){}".format(s[0]), repl, s, flags=re.I)
Demo:
In [5]: s = "Bobble"
In [6]: ign_first(s, "*")
Out[6]: 'Bo**le'
Or use str.join with a set:
def ign_first(s, repl):
first_ch = s[0]
st = {first_ch, first_ch.lower()}
return first_ch + "".join([repl if ch in st else ch for ch in s[1:]])
Demo:
In [10]: ign_first(s, "*")
Out[10]: 'Bo**le'
I would use slices and lower().
>>> test = 'Bobble'
>>> test[0] + test[1:].lower().replace(test[0].lower(), '*')
'Bo**le'
There's no need to use additional variables
>>> st='Bobble'
>>> st=st[0]+st[1:].lower().replace(st[0].lower(),'*')
>>> st
'Bo**le'
case-insensitive solution with regular expressions:
import re
string = "Bobble"
outcome = string[0]+re.sub(string[0].lower() + '|' + string[0].upper(),
"*", string[1:].lower())
>>>
Bo**le

Python - making a function that would add "-" between letters

I'm trying to make a function, f(x), that would add a "-" between each letter:
For example:
f("James")
should output as:
J-a-m-e-s-
I would love it if you could use simple python functions as I am new to programming. Thanks in advance. Also, please use the "for" function because it is what I'm trying to learn.
Edit:
yes, I do want the "-" after the "s".
Can I try like this:
>>> def f(n):
... return '-'.join(n)
...
>>> f('james')
'j-a-m-e-s'
>>>
Not really sure if you require the last 'hyphen'.
Edit:
Even if you want suffixed '-', then can do like
def f(n):
return '-'.join(n) + '-'
As being learner, it is important to understand for your that "better to concat more than two strings in python" would be using str.join(iterable), whereas + operator is fine to append one string with another.
Please read following posts to explore further:
Any reason not to use + to concatenate two strings?
which is better to concat string in python?
How slow is Python's string concatenation vs. str.join?
Also, please use the "for" function because it is what I'm trying to learn
>>> def f(s):
m = s[0]
for i in s[1:]:
m += '-' + i
return m
>>> f("James")
'J-a-m-e-s'
m = s[0] character at the index 0 is assigned to the variable m
for i in s[1:]: iterate from the second character and
m += '-' + i append - + char to the variable m
Finally return the value of variable m
If you want - at the last then you could do like this.
>>> def f(s):
m = ""
for i in s:
m += i + '-'
return m
>>> f("James")
'J-a-m-e-s-'
text_list = [c+"-" for c in text]
text_strung = "".join(text_list)
As a function, takes a string as input.
def dashify(input):
output = ""
for ch in input:
output = output + ch + "-"
return output
Given you asked for a solution that uses for and a final -, simply iterate over the message and add the character and '-' to an intermediate list, then join it up. This avoids the use of string concatenations:
>>> def f(message)
l = []
for c in message:
l.append(c)
l.append('-')
return "".join(l)
>>> print(f('James'))
J-a-m-e-s-
I'm sorry, but I just have to take Alexander Ravikovich's answer a step further:
f = lambda text: "".join([c+"-" for c in text])
print(f('James')) # J-a-m-e-s-
It is never too early to learn about list comprehension.
"".join(a_list) is self-explanatory: glueing elements of a list together with a string (empty string in this example).
lambda... well that's just a way to define a function in a line. Think
square = lambda x: x**2
square(2) # returns 4
square(3) # returns 9
Python is fun, it's not {enter-a-boring-programming-language-here}.

In python, how can I use regex to replace square bracket with parentheses

I have a list :list = [1,2,3]. And I would like to convert that into a string with parentheses: string = (1,2,3).
Currently I am using string replace string = str(list).replace('[','(').replace(']',')'). But I think there is a better way using regex.sub. But I have no idea how to do it. Thanks a lot
If you do indeed have a list, then:
>>> s = [1,2,3]
>>> str(tuple(s))
'(1, 2, 3)'
You could use string.maketrans instead -- I'm betting it runs faster than a sequence of str.replace and it scales better to more single character replacements.
>>> import string
>>> table = string.maketrans('[]','()')
>>> s = "[1, 2, 3, 4]"
>>> s.translate(table)
'(1, 2, 3, 4)'
You can even use this to remove characters from the original string by passing an optional second argument to str.translate:
>>> s = str(['1','2'])
>>> s
"['1', '2']"
>>> s.translate(table,"'")
'(1, 2)'
In python3.x, the string module is gone and you gain access to maketrans via the str builtin:
table = str.maketrans('[]','()')
There are a billion ways to do this, as demonstrated by all the answers. Here's another one:
my_list = [1,2,3]
my_str = "(%s)" % str(my_list).strip('[]')
or make it recyclable:
list_in_parens = lambda l: "(%s)" % str(l).strip('[]')
my_str = list_in_parens(my_list)
str([1,2,3]).replace('[','(').replace(']',')')
Should work for you well, and it is forward and backward compatible as far as I know.
as far as re-usability, you can use the following function for multiple different types of strings to change what they start and end with:
def change(str_obj,start,end):
if isinstance(str_obj,str) and isinstance(start,str) and isinstance(end,str):
pass
else:
raise Exception("Error, expecting a 'str' objects, got %s." % ",".join(str(type(x)) for x in [str_obj,start,end]))
if len(str_obj)>=2:
temp=list(str_obj)
temp[0]=start
temp[len(str_obj)-1]=end
return "".join(temp)
else:
raise Exception("Error, string size must be greater than or equal to 2. Got a length of: %s" % len(str_obj))
All you need is:
"(" + strng.strip('[]') + ")"
It works for both single element and multi-element lists.
>>> lst = [1,2,3]
>>> strng = str(lst)
>>> "(" + strng.strip('[]') + ")"
'(1, 2, 3)'
>>> lst = [1]
>>> strng = str(lst)
>>> "(" + strng.strip('[]') + ")"
'(1)'
If you really want to use regex I guess this would work. But the other posted solutions are probably more efficient and/or easy to use.
import re
string = str(list)
re.sub(r"[\[]", "(", string)
re.sub(r"[\]]", ")", string)
#mgilson something like this you mean?
def replace_stuff(string):
string_list = list(string)
pattern = re.compile(r"[\[\]]")
result = re.match(pattern, string)
for i in range(len(result.groups())):
bracket = result.group(i)
index = bracket.start()
print(index)
if bracket == "[":
string_list[index] = "("
else:
string_list[index] = ")"
return str(string_list)
It doesn't quite work, for some reason len(result.groups()) is always 0 even though the regex should find matches. So couldn't test whether this is faster but because I couldn't get it to work I couldn't test it. I have to leave for bed now so if someone can fix this go ahead.
Try this:
'({0})'.format(', '.join(str(x) for x in list))
By the way, it's not a good idea to name your own variables list since it clashes with the built-in function. Also string can conflict with the module of the same name.

Categories

Resources