I wrote a quick script to remove the 'http://' substring from a list of website addresses saved on an excel column. The function replace though, doesn't work and I don't understand why.
from openpyxl import load_workbook
def rem(string):
print string.startswith("http://") #it yields "True"
string.replace("http://","")
print string, type(string) #checking if it works (it doesn't though, the output is the same as the input)
wb = load_workbook("prova.xlsx")
ws = wb["Sheet"]
for n in xrange(2,698):
c = "B"+str(n)
print ws[c].value, type(ws[c].value) #just to check value and type (unicode)
rem(str(ws[c].value)) #transformed to string in order to make replace() work
wb.save("prova.xlsx") #nothing has changed
String.replace(substr)
does not happen in place, change it to:
string = string.replace("http://","")
string.replace(old, new[, max]) only returns a value—it does not modify string. For example,
>>> a = "123"
>>> a.replace("1", "4")
'423'
>>> a
'123'
You must re-assign the string to its modified value, like so:
>>> a = a.replace("1", "4")
>>> a
'423'
So in your case, you would want to instead write
string = string.replace("http://", "")
Related
I tried this code to do simple string replacement:
X = "hello world"
X.replace("hello", "goodbye")
Why doesn't X change, from "hello world" to "goodbye world"?
This is because strings are immutable in Python.
Which means that X.replace("hello","goodbye") returns a copy of X with replacements made. Because of that you need replace this line:
X.replace("hello", "goodbye")
with this line:
X = X.replace("hello", "goodbye")
More broadly, this is true for all Python string methods that change a string's content "in-place", e.g. replace,strip,translate,lower/upper,join,...
You must assign their output to something if you want to use it and not throw it away, e.g.
X = X.strip(' \t')
X2 = X.translate(...)
Y = X.lower()
Z = X.upper()
A = X.join(':')
B = X.capitalize()
C = X.casefold()
and so on.
All string functions as lower, upper, strip are returning a string without modifying the original. If you try to modify a string, as you might think well it is an iterable, it will fail.
x = 'hello'
x[0] = 'i' #'str' object does not support item assignment
There is a good reading about the importance of strings being immutable: Why are Python strings immutable? Best practices for using them
Example for String Methods
Given a list of filenames, we want to rename all the files with extension hpp to the extension h. To do this, we would like to generate a new list called newfilenames, consisting of the new filenames.
filenames = ["program.c", "stdio.hpp", "sample.hpp", "a.out", "math.hpp", "hpp.out"]
# Generate newfilenames as a list containing the new filenames
# using as many lines of code as your chosen method requires.
newfilenames = []
for i in filenames:
if i.endswith(".hpp"):
x = i.replace("hpp", "h")
newfilenames.append(x)
else:
newfilenames.append(i)
print(newfilenames)
# Should be ["program.c", "stdio.h", "sample.h", "a.out", "math.h", "hpp.out"]
'zipcodes.txt' is a text file with just zipcodes. The script works correct if I just enter a zipcode e.g. "90210". zip_list[0] type is a string and when printed it returns a single zipcode. However with the code as is a keep getting 'None'
from uszipcode import SearchEngine
search = SearchEngine(simple_zipcode=False)
zip_list = list(open("zipcodes.txt","r"))
search_by_zip = search.by_zipcode(zip_list[0])
print(search_by_zip.major_city)
I changed the variable names around a bit to make sense for me, but I had to strip() the list to get rid of the '\n'
first_list = list(open("zipcodes.txt","r"))
zip_list = []
for item in first_list:
zip_list.append(item.strip())
I tried this code to do simple string replacement:
X = "hello world"
X.replace("hello", "goodbye")
Why doesn't X change, from "hello world" to "goodbye world"?
This is because strings are immutable in Python.
Which means that X.replace("hello","goodbye") returns a copy of X with replacements made. Because of that you need replace this line:
X.replace("hello", "goodbye")
with this line:
X = X.replace("hello", "goodbye")
More broadly, this is true for all Python string methods that change a string's content "in-place", e.g. replace,strip,translate,lower/upper,join,...
You must assign their output to something if you want to use it and not throw it away, e.g.
X = X.strip(' \t')
X2 = X.translate(...)
Y = X.lower()
Z = X.upper()
A = X.join(':')
B = X.capitalize()
C = X.casefold()
and so on.
All string functions as lower, upper, strip are returning a string without modifying the original. If you try to modify a string, as you might think well it is an iterable, it will fail.
x = 'hello'
x[0] = 'i' #'str' object does not support item assignment
There is a good reading about the importance of strings being immutable: Why are Python strings immutable? Best practices for using them
Example for String Methods
Given a list of filenames, we want to rename all the files with extension hpp to the extension h. To do this, we would like to generate a new list called newfilenames, consisting of the new filenames.
filenames = ["program.c", "stdio.hpp", "sample.hpp", "a.out", "math.hpp", "hpp.out"]
# Generate newfilenames as a list containing the new filenames
# using as many lines of code as your chosen method requires.
newfilenames = []
for i in filenames:
if i.endswith(".hpp"):
x = i.replace("hpp", "h")
newfilenames.append(x)
else:
newfilenames.append(i)
print(newfilenames)
# Should be ["program.c", "stdio.h", "sample.h", "a.out", "math.h", "hpp.out"]
basically I need to find if a string (actually a Path) is inside a similar string but more long.
I have this string in a list:
/aa/bb/cc
/aa/bb/cc/11
/aa/bb/cc/22
/aa/bb/dd
/aa/bb/dd/33
/aa/bb/dd/44
I expect to put inside a list only string like:
/aa/bb/cc/11
/aa/bb/cc/22
/aa/bb/dd/33
/aa/bb/dd/44
I need a new list without /aa/bb/cc and /aa/bb/dd because exists /aa/bb/cc/11 and /aa/bb/cc/22, same for /aa/bb/dd, exists /aa/bb/dd/33 and /aa/bb/dd/44 so I do not want the base form /aa/bb/cc and /aa/bb/dd.
I hope I was clear :-D
How can I do thet in Python 3?
Regards
Use regular expressions.
import re
list_1 = ["/aa/bb/cc",
"/aa/bb/cc/11",
"/aa/bb/cc/22",
"/aa/bb/dd",
"/aa/bb/dd/33",
"/aa/bb/dd/44"]
regex = re.compile(r'/aa/bb/cc/+.')
obj = filter(regex.search, list_1)
regex2 = re.compile(r'/aa/bb/dd/+.')
obj2 = filter(regex2.search, list_1)
print(list(obj))
print(list(obj2))
Output:
['/aa/bb/cc/11', '/aa/bb/cc/22']
['/aa/bb/dd/33', '/aa/bb/dd/44']
I know that the following is how to replace a string with another string i
line.replace(x, y)
But I only want to replace the second instance of x in the line. How do you do that?
Thanks
EDIT
I thought I would be able to ask this question without going into specifics but unfortunately none of the answers worked in my situation. I'm writing into a text file and I'm using the following piece of code to change the file.
with fileinput.FileInput("Player Stats.txt", inplace=True, backup='.bak') as file:
for line in file:
print(line.replace(chosenTeam, teamName), end='')
But if chosenTeam occurs multiple times then all of them are replaced.
How can I replace only the nth instance in this situation.
That's actually a little tricky. First use str.find to get an index beyond the first occurrence. Then slice and apply the replace (with count 1, so as to replace only one occurrence).
>>> x = 'na'
>>> y = 'banana'
>>> pos = y.find(x) + 1
>>> y[:pos] + y[pos:].replace(x, 'other', 1)
'banaother'
Bonus, this is a method to replace "NTH" occurrence in a string
def nth_replace(str,search,repl,index):
split = str.split(search,index+1)
if len(split)<=index+1:
return str
return search.join(split[:-1])+repl+split[-1]
example:
nth_replace("Played a piano a a house", "a", "in", 1) # gives "Played a piano in a house"
You can try this:
import itertools
line = "hello, hi hello how are you hello"
x = "hello"
y = "something"
new_data = line.split(x)
new_data = ''.join(itertools.chain.from_iterable([(x, a) if i != 2 else (y, a) for i, a in enumerate(new_data)]))