Surround strings in a list with a certain character - python

I have a list consisting of strings and I need to surround each of the strings with asterisks. With the input:
def addAsterisks(["abc", "ded"])
The output should be:
["*abc*", "*ded*"]
Here is what I have tried:
for x in strs:
x = "*" + x + "*"
However, the output is unchanged:
["abc", "ded"]

x is a local variable, so changing it is meaningless once it goes out of scope. You could, e.g., return the modified list and assign it somewhere:
def addAsterisks(l)
return ['*' + x + '*' for x in l]
myList = addAsterisks(["abc", "ded"])

You can use, also, str.format():
def addAsterisks(a):
# Or:
# return ["*%s*" %k for k in a]
return ["*{}*".format(k) for k in a]
print(addAsterisks(["abc", "ded"]))
>>> ['*abc*', '*ded*

You have to modify the list to reflect changes in your list. I used inline function for compact code.
Code
['*'+ i + "*" for picture in pictures]
input
["abc", "def"]
Output
["*abc*", "*def*"]

Modify the the array and return to where you want to use. Modifying a temp variable (x) wont work since u will loose it once you are out of scope.
def addAsterisks(string_list):
return ['*' + x + '*' for x in string_list]
print addAsterisks(["abc", "ded"])
This will output:
['*abc*', '*ded*']

You are assigning to a temporary variable x, which does not change the actual list. Try instead
return ["*" + x + "*" for x in picture]
or, if you want a loop:
for i,x in enumerate(picture):
picture[i] = "*" + x + "*"

You can also do like this:
In [22]: def addAsterisks(s):
...: newarr = []
...: for i in s:
...: newstr = "*" + str(i) + "*"
...: newarr.append(newstr)
...: print(newarr)
...:
In [23]: addAsterisks(["abc", "ded"])
['*abc*', '*ded*']

Here is the Pythonic way of tackling this question:
A = [ "*"+a+"*" for a in picture ]
Hint: Read about list comprehension in Python.

I'm late at the party.
Other solutions are better for the specific use case, but this might help someone else (it is a totally different approach from other answers).
If you are really sure about the length of each string to be exactly three, you can do the following:
def addAsterisks(items):
return [ f'{value:*^5}' for value in items ]
addAsterisks(["abc","def"])
Please note that if you change 5 to 7 you will surrond each string with 2 asterisks

Related

Python use in the same line "For", "If" and "Else"

I want to learn python "secrets", it's possible to put all this code in one line?:
word_not_clean="Casà: 25$"
word_clean=""
for x in word_not_clean:
if x in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789':
word_clean+=x
else:
word_clean+='_'
This sentences work, but no replace especial characters:
word_clean="".join(x for x in word_not_clean if x in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
But this sentence with else doesn't works.
word_clean="".join(x for x in word_not_clean if x in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' else '_')
Thank you in advance.
If you want to do it using list comprehension (one-lining lines) add the if-else statement before the for:
chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
word_clean = "".join([x if x in chars else '_' for x in word_not_clean])
You can try like the below and also, you can use string.ascii_uppercase + string.ascii_lowercase + string.digits.
import string
word_not_clean="Casà: 25$"
chars_check = string.ascii_uppercase + string.ascii_lowercase + string.digits
result = ''.join(x if x in chars_check else '_' for x in word_not_clean)
print(result)
# 'Cas___25_'
Explanation:
>>> import string
>>> string.ascii_uppercase + string.ascii_lowercase + string.digits
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
There are two different kinds of if statements in generator expressions. The first kind (which I’ll call an “inclusion if”) comes after the for statement, and indicates whether a given item from an iterator should be included in the resultant list. This is what you’re using in the first example.
The second kind (which I’ll call a “ternary if”) comes before the if statement, and used Python’s ternary operator __ if __ else __ to decide what should be outputted by the iterator. This is what you want for the second example, but you need to reorder your terms:
OKAY = “abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789”
word_clean = "".join(
x if x in OKAY else '_' # Ternary if
for x in word_not_clean
)

Replacing strings, not characters without the use of .replace and joining the strings the characters

Question has been asked that is similar but all post on here refer to replacing single characters. I'm trying to replace a whole word in a string. I've replaced it but I cant print it with spaces in between.
Here is the function replace that replaces it:
def replace(a, b, c):
new = b.split()
result = ''
for x in new:
if x == a:
x = c
result +=x
print(' '.join(result))
Calling it with:
replace('dogs', 'I like dogs', 'kelvin')
My result is this:
i l i k e k e l v i n
What I'm looking for is:
I like kelvin
The issue here is that result is a string and when join is called it will take each character in result and join it on a space.
Instead, use a list , append to it (it's also faster than using += on strings) and print it out by unpacking it.
That is:
def replace(a, b, c):
new = b.split(' ')
result = []
for x in new:
if x == a:
x = c
result.append(x)
print(*result)
print(*result) will supply the elements of the result list as positional arguments to print which prints them out with a default white space separation.
"I like dogs".replace("dogs", "kelvin") can of course be used here but I'm pretty sure that defeats the point.
Substrings and space preserving method:
def replace(a, b, c):
# Find all indices where 'a' exists
xs = []
x = b.find(a)
while x != -1:
xs.append(x)
x = b.find(a, x+len(a))
# Use slice assignment (starting from the last index)
result = list(b)
for i in reversed(xs):
result[i:i+len(a)] = c
return ''.join(result)
>>> replace('dogs', 'I like dogs dogsdogs and hotdogs', 'kelvin')
'I like kelvin kelvinkelvin and hotkelvin'
Just make result a list, and the joining will work:
result = []
You are just generating one long string and join its chars.

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}.

why can't I use if x == "T" x == " " to replace T

I want to write a function, replacing T by space.
b=""
xs=list("fghtThjchk")
for x in xs:
if x=="T" or "t":
x==" "
b=b+x
I can do it with .replace, but I still want to know can I use list to do it.
x==" " isn't the same as x=" " which is why b is getting the wrong value
if x=="T" or "t": doesn't mean "is x one of 'T' or 't'". You need to say it like this if x in 'Tt': or this if x=="T" or x=="t":
Perhaps this is what you are trying to do
b = ""
for x in "fghtThjchk":
if x == "T" or x == "t":
x = " "
b = b + x
This line doesn't do what you want
if x=="T" or "t":
That condition always evaluates to true, because "t" is considered truthy.
You mean
if x=="T" or x=="t":
And the line that says
x==" "
was meant, I guess, to be an assignment and not a comparison:
x=" "
The syntax you are using is little bit incorrect.
The correct way of using if/else in list comprehensions is given below:
''.join([' ' if x=='T' or x=='t' else x for x in xs])
-- This method is littler faster & optimized when the string is of large length.
-- We are creating string objects again & again in above answers, which is not recommended.
-- So always use join() to join the list after performing all the operations on it instead of string concatenation in loops.
We can make use of the re (Regular Expression) module, which is fast:
import re
aa = re.sub(r'([.tT])', " ", "fghtThjchk")
You need to reference the list by index, such as this:
for i, x in enumerate(xs):
if x in ["T", "t"]:
xs[i] = " "
When you do for x in xs you're assigning the name x to each element of xs one at a time. When you do x=" " (I presume == was a typo) you're reassigning the name x but not changing the original element in xs.

How to downcase the first character of a string?

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/

Categories

Resources