Strings and appending in Python - python

In Python a string is immutable. I find the function string.join() could add the value to a string but it seems the following doesn't work.
#coding: utf-8
if __name__ == "__main__":
str = "A fox has jumped into the river"
tmp = ""
for i in str:
tmp = tmp.join(i)
print tmp
I expect the output should be "A fox has jumped into the river", but it output the "r"
why?
Is there any similar methods which is something like string.append()?

>>> a = "pp"
>>> b = "kk"
>>> a += b
>>> a
'ppkk'

You can append simply by using +:
tmp = tmp + i
which can be combined with an in-place addition assignment:
tmp += i
but this is not nearly as efficient as joining the whole sequence with ''.join():
str = "A fox has jumped into the river"
tmp = ''.join(str)
The latter is of course, rather pointless, as we just took all individual characters of str, and rejoined them into a new, otherwise equal, string. But it is far more efficient than calling + in a loop, as .join() only has to create a new string once, while a loop with + creates new strings for each concatenation.
It gets more interesting when you use a delimiter:
>>> ' - '.join(str)
'A - - f - o - x - - h - a - s - - j - u - m - p - e - d - - i - n - t - o - - t - h - e - - r - i - v - e - r'
The thing to note here is that you call .join() on the delimiter string, not on the sequence you are about to join!

>>> '-'.join('a')
'a'
str.join doesn't work like that. That's the reason why "r" is the output, since at the end of the for loop you have set tmp = tmp.join('r') whichc will just result in "r".
This is how str.join is usually used:
>>> '-'.join('abc')
'a-b-c'
or
>>> ', '.join(['foo', 'bar', 'spam'])
'foo, bar, spam'
You want simple string concatenation
tmp = ""
for i in str:
tmp += i
or use a list and ''.join for efficient string concatenation (the former solution is O(N^2) due to the immutable nature of strings)
tmp = []
for i in str:
tmp.append(i)
tmp = ''.join(tmp)
(''.join joins the list into a string with an empty string as a separator)
One last note: don't use str as a variable name, it's a built-in.

This will do what you want i think:
if __name__ == "__main__":
str = "A fox has jumped into the river"
tmp = ""
for i in str:
tmp += i
print (tmp)
The reason you code doesn't work is that join joins all the tokens in the list you are providing, seperated by whatever string you "apply" it to. It doesn't actually append to a string.

Related

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

How to fill an empty string which has already been created in python

I have created an empty string:
s = ""
how can I append text to it?
I know how to append something to a list like:
list.append(something)
but how one can append something to an empty string?
The right name would be to concatenate a string to another, you can do this with the + operator:
s = ""
s = s + "some string"
print s
>>> "some string"
like this:
s += "blabla"
Please note that since strings are immutable, each time you concatenate, a new string object is returned.
Strings are immutable in Python, you cannot add to them. You can, however, concatenate two or more strings together to make a third string.
>>> a = "My string"
>>> b = "another string"
>>> c = " ".join(a, b)
>>> c
"My string another string"
While you can do this:
>>> a = a + " " + b
>>> a
"My string another string"
you are not actually adding to the original a, you are creating a new string object and assigning it to a.
Python str's (strings) are immutable (not modifiable). Instead, you create a new string and assign to the original variable, allowing the garbage collector to eventually get rid of the original string.
However, array.array('B', string) and bytearray are mutable.
Here's an example of using a mutable bytearray:
#!/usr/local/cpython-3.3/bin/python
string = 'sequence of characters'
array = bytearray(string, 'ISO-8859-1')
print(array)
array.extend(b' - more characters')
print(array)
print(array.decode('ISO-8859-1'))
HTH
ls = "sts"
temp = ""
for c in range(len(ls)-1, -1, -1):
temp += ls[c]
if(temp == ls):
print("Palindrome")
else:
print("not")
This line is your answer : temp += ls[c]

Pascal funcs Insert/Delete in Python

Delphi has functions
Insert (insert substring Str2 into string Str at offset P) and
Delete (delete N chars from string Str at offset P).
What is analog of them in Python for strings?
You can use
s1[:p] + s2 + s1[p:]
s1[:p] + s1[p+n:]
For example:
>>> s1 = 'hello world'
>>> s2 = 'xyz'
>>> p = 3
>>> s1[:p] + s2 + s1[p:]
'helxyzlo world'
>>> n = 2
>>> s1[:p] + s1[p+n:]
'hel world'
Python strings are immutable, so you can't modify an existing string -- but you can apply those operations to a string and produce a new one.
Probably the best way to do it is slicing, an extension of the indexing syntax to allow you to pull out multiple characters. So:
>>> 'abcde'[1:4]
'bcd'
Notice that the first index is inclusive, but the second index is exclusive. That's weird at first, but it's a ubiquitous convention in Python.
If you leave out the first or last index, the slice goes to the beginning or end of the string, respectively:
>>> 'abcde'[1:]
'bcde'
>>> 'abcde'[:4]
'abcd'
Finally, you can use the + operator for string concatenation:
>>> 'abc' + 'de'
'abcde'
With all these parts together, you can insert and delete substrings as you like:
>>> s = 'abcde'
>>> s[:2] + 'XYZ' + s[2:] # Insert 'XYZ' before index 2
'abXYZcde'
>>> s[:2] + s[4:] # Delete indices from 2 to before 4
'abe'
If you wanted insert and delete functions as you've described them, you'd be writing them yourself -- but that wouldn't be hard. Spoiler alert -- you may want to give it a try yourself before reading the code below. :)
def insert(str, str2, p):
return str[:p] + str2 + str[p:]
def delete(str, p, n):
return str[:p] + str[p + n:]
(You could probably come up with better argument names -- in particular, using str is inadvisable because it's also the name of a Python builtin -- but for this example I've intentionally used the same ones you used in the question.)

'str' object does not support item assignment [duplicate]

This question already has answers here:
Changing one character in a string
(15 answers)
Closed last month.
I would like to read some characters from a string s1 and put it into another string s2.
However, assigning to s2[j] gives an error:
s2[j] = s1[i]
# TypeError: 'str' object does not support item assignment
In C, this works:
int i = j = 0;
while (s1[i] != '\0')
s2[j++] = s1[i++];
My attempt in Python:
s1 = "Hello World"
s2 = ""
j = 0
for i in range(len(s1)):
s2[j] = s1[i]
j = j + 1
The other answers are correct, but you can, of course, do something like:
>>> str1 = "mystring"
>>> list1 = list(str1)
>>> list1[5] = 'u'
>>> str1 = ''.join(list1)
>>> print(str1)
mystrung
>>> type(str1)
<type 'str'>
if you really want to.
In Python, strings are immutable, so you can't change their characters in-place.
You can, however, do the following:
for c in s1:
s2 += c
The reasons this works is that it's a shortcut for:
for c in s1:
s2 = s2 + c
The above creates a new string with each iteration, and stores the reference to that new string in s2.
assigning to s2[j] gives an error
Strings are immutable so what you've done in C won't be possible in Python. Instead, you'll have to create a new string.
I would like to read some characters from a string and put it into
other string.
Use a slice:
>>> s1 = 'Hello world!!'
>>> s2 = s1[6:12]
>>> print(s2)
world!
Strings in Python are immutable (you cannot change them inplace).
What you are trying to do can be done in many ways:
Copy the string:
foo = 'Hello'
bar = foo
Create a new string by joining all characters of the old string:
new_string = ''.join(c for c in oldstring)
Slice and copy:
new_string = oldstring[:]
Performant methods
If you are frequently performing index replacements, a more performant and memory-compact method is to convert to a different data structure. Then, convert back to string when you're done.
list:
Easiest and simplest:
s = "TEXT"
s = list(s)
s[1] = "_"
s = "".join(s)
bytearray (ASCII):
This method uses less memory. The memory is also contiguous, though that doesn't really matter much in Python if you're doing single-element random access anyways:
ENC_TYPE = "ascii"
s = "TEXT"
s = bytearray(s, ENC_TYPE)
s[1] = ord("_")
s = s.decode(ENC_TYPE)
bytearray (UTF-32):
More generally, for characters outside the base ASCII set, I recommend using UTF-32 (or sometimes UTF-16), which will ensure alignment for random access:
ENC_TYPE = "utf32"
ENC_WIDTH = 4
def replace(s, i, replacement):
start = ENC_WIDTH * (i + 1)
end = ENC_WIDTH * (i + 2)
s[start:end] = bytearray(replacement, ENC_TYPE)[ENC_WIDTH:]
s = "TEXT HI ひ RA ら GA が NA な DONE"
s = bytearray(s, ENC_TYPE)
# Performs s[1] = "_"
replace(s, 1, "_")
s = s.decode(ENC_TYPE)
Though this method may be more memory-compact than using list, it does require many more operations.
Other answers convert the string to a list or construct a new string character by character. These methods can be costly, especially for large strings. Instead, we can use slicing to get the parts of the string before and after the character that is changed, and combine those with the new character.
Here I modify the example code from Crowman's answer to replace a single character in the string using string slicing instead of conversion to a list.
>>> str1 = "mystring"
>>> pos = 5
>>> new_char = 'u'
>>> str2 = str1[:pos] + new_char + str1[pos+1:]
>>> print(str2)
mystrung
>>> type(str2)
<class 'str'>
Another approach if you wanted to swap out a specific character for another character:
def swap(input_string):
if len(input_string) == 0:
return input_string
if input_string[0] == "x":
return "y" + swap(input_string[1:])
else:
return input_string[0] + swap(input_string[1:])
The 'str' is an immutable data type. Therefore str type object doesn't support item assignment.
s1 = "Hello World"
s2 = ['']*len(s1)
j = 0
for i in range(len(s1)):
s2[j]=s1[i]
j = j + 1
print(''.join(s2)) # Hello World
How about this solution:
str="Hello World" (as stated in problem)
srr = str+ ""
Hi you should try the string split method:
i = "Hello world"
output = i.split()
j = 'is not enough'
print 'The', output[1], j

Categories

Resources