I feel like this is a really simple question,
but I need help figuring out.
So, I have the following:
str = 'hello world'
str.split() # ['hello','world']
I want to index 'world' but str[1] returns 'e', which is the second character in the list.
How do I index by word instead of character?
Please help me out and thank you in advance.
(Please don't tell me to do str[5:]... I wanna know how to index words in general)
You need to index the result of my_str.split():
my_str = "hello world"
words = my_str.split()
print words[1]
(Renamed the variable to my_str to avoid shadowing the built-in.)
Note that my_str.split() does not change my_str in any way. String objects are immutable in Python and can't be changed. Instead, my_str.split() returns a list of strings that can be indexed.
str is your string, not the result of str.split(). You need to assign the result to something (preferably something not called str, since that's the name of the builtin str type and also a rather bad name to use for a list, even one returned from str.split().
>>> s = 'hello world'
>>> l = s.split()
>>> l[1]
'world'
You're indexing str, which is a string (you didn't reassign value to str after splitting so it went down the drain).
Use
str.split()[1]
or even better save the split result, and index that:
spl = str.split()
spl[1]
The split returns a list, instead of splitting in place:
str = 'hello world'
str_words = str.split() # split returns a list
print str_words[0] # prints first word "hello"
Related
I have a unicode string:
s = "ᠤᠷᠢᠳᠤ ᠲᠠᠯᠠ ᠶᠢᠨ ᠬᠠᠪᠲᠠᠭᠠᠢ ᠬᠡᠪᠲᠡᠭᠡ"
the split method it returns is somewhat changed, with a \u180e in the second word.
>>> print(s.split())
['ᠤᠷᠢᠳᠤ', 'ᠲᠠᠯ\u180eᠠ', 'ᠶᠢᠨ', 'ᠬᠠᠪᠲᠠᠭᠠᠢ', 'ᠬᠡᠪᠲᠡᠭᠡ']
What I want to get is:
['ᠤᠷᠢᠳᠤ', 'ᠲᠠᠯᠠ ᠶᠢᠨ', 'ᠶᠢᠨ', 'ᠬᠠᠪᠲᠠᠭᠠᠢ', 'ᠬᠡᠪᠲᠡᠭᠡ']
What is the reason causing this, and how to solve it?
I don't think the problem is with the split function, but with the list itself.
>>> s = ["ᠤᠷᠢᠳᠤ ᠲᠠᠯᠠ ᠶᠢᠨ ᠬᠠᠪᠲᠠᠭᠠᠢ ᠬᠡᠪᠲᠡᠭᠡ"]
>>> print(s)
['ᠤᠷᠢᠳᠤ ᠲᠠᠯ\u180eᠠ ᠶᠢᠨ ᠬᠠᠪᠲᠠᠭᠠᠢ ᠬᠡᠪᠲᠡᠭᠡ']
You should still be able to use the list normally, because it corrects itself when the element is used.
>>> s = "ᠤᠷᠢᠳᠤ ᠲᠠᠯᠠ ᠶᠢᠨ ᠬᠠᠪᠲᠠᠭᠠᠢ ᠬᠡᠪᠲᠡᠭᠡ"
>>> s = s.split()
>>> [print(e) for e in s]
ᠤᠷᠢᠳᠤ
ᠲᠠᠯᠠ
ᠶᠢᠨ
ᠬᠠᠪᠲᠠᠭᠠᠢ
ᠬᠡᠪᠲᠡᠭᠡ
According to Wikipedia: https://en.wikipedia.org/wiki/Whitespace_character#Unicode
U+180E is a space character until Uncode 6.3.0 so if python implements a earlier Unicode spec than i guess split() would break on all space characters. You could work arround this by giving split an argument if you want to only split on certain characters (s.split(" ")) that would give you:
>>> s.split(" ")
['ᠤᠷᠢᠳᠤ', 'ᠲᠠᠯ\u180eᠠ\u202fᠶᠢᠨ', 'ᠬᠠᠪᠲᠠᠭᠠᠢ', 'ᠬᠡᠪᠲᠡᠭᠡ']
I have been noticing a problem I am having whenever I try to make a function that takes changes a string or a list then returns it.
I will give you an example of this happening with a code I just wrote:
def remove_exclamation(string):
string.split(' ')
for i in string:
i.split()
for char in i:
if char == '!':
del char
''.join(i)
' '.join(string)
return string
For instance, I create this code to take a string as its parameter, remove any exclamation in it, the return it changed. The input and output should look like this:
>>>remove_exclamation('This is an example!')
'This is an example'
But instead I get this:
>>>remove_exclamation('This is an example!')
'This is an example!'
The function is not removing the exclamation in the output, and is not doing what I intended for it to day.
How can I keep avoiding this when I make for loops, nested for loops etc?
You write your code and formulate your question as if it was possible to modify strings in Python. It is not possible.
Strings are immutable. All functions which operate on strings return new strings. They do not modify existing strings.
This returns a list of strings, but you are not using the result:
string.split(' ')
This also:
i.split()
This deletes the variable named char. It does not affect the char itself:
del char
This creates a new string which you do not use:
''.join(i)
This also:
' '.join(string)
All in all, almost every line of the code is wrong.
You probably wanted to do this:
def remove_exclamation(string):
words = string.split(' ')
rtn_words = []
for word in words:
word_without_exclamation = ''.join(ch for ch in word if ch != '!')
rtn_words.append(word_without_exclamation)
return ' '.join(rtn_words)
But in the end, this does the same thing:
def remove_exclamation(string):
return string.replace('!', '')
Without clearly knowing the intentions of your function and what you are attempting to do. I have an alternative to the answer that zvone gave.
This option is to remove any characters that you have not defined in an allowed characters list:
characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ "
test_string = "This is an example!"
test_string = ''.join(list(filter(lambda x: x in characters, test_string)))
print(test_string)
This outputs:
This is an example
Note, this is the Python 3 version.
Python 2, you do not need the ''.join(list())
Doing it this way would allow you to define any character that you do not want present in your string, and it will remove them.
You can even do the reverse:
ignore_characters= "!"
test_string = "This is an example!"
test_string = ''.join(list(filter(lambda x: x not in ignore_characters, test_string)))
print(test_string)
Strings are immutable in Python. And you cannot change them. You can however, re-assign there values.
That is where your problem lies. You never reassign the value of your strings, when you call .split() on them.
But there are also others errors in your program such as:
Your indention
The fact that your just returning the string thats passed into the function
Your use of the del statement
etc.
Instead, create a new string by iterating through the old one and filtering out the character(s) you do not want, via list comprehension and ''.join().
def remove_exclamation(string):
return ''.join([char for char in string if char != '!'])
But as #Moses has already said in the comments, why not just use str.replace()?:
string = string.replace('!', '')
def remove_exclamation(string):
#you think you are splitting string into tokens
#but you are not assigning the split anywhere...
string.split(' ')
#and here you are cycling through individual _chars_ in string which was not affected by the split above ;-)
for i in string:
#and now you are splitting a 1-char string and again not assigning it.
i.split()
And string is still your input param, which I assume is of type str. And immutable.
On top of which, if you were import/using the string module, you would be shadowing it
A big part of your confusion is knowing when the methods mutate the objects and when they return a new object. In the case of strings, they never mutate, you need to assign the results to a new variable.
On a list however, and the join() somewhere makes me think you want to use a list, then methods generally change the object in place.
Anyway, on to your question:
def remove_exclamation(inputstring, to_remove="!"):
return "".join([c for c in inputstring if c != to_remove])
print (remove_exclamation('This is an example!'))
output:
This is an example
def remove_char(text):
for letter in text[1]:
text[0] = text[0].replace(letter," ")
return text[0]
This is returning:
'str' object does not support item assignment
Why? And how can I make this work?
In Python, strings are not mutable, which means they cannot be changed. You can, however, replace the whole variable with the new version of the string.
Example:
text = ' ' + text[1:] # replaces first character with space
Strings are immutable. By trying:
text[0] = text[0].replace(letter," ")
you are trying to access the string and change it, which is disallowed due to the string's immutability. Instead, you can use a for loop and some slicing:
for i in range(0, len(y)):
if y[i] == ",":
print y[i+1:len(y)]
break
You can change the string a variable is assigned to (second piece of code) rather than the string itself (your piece of code).
Assuming that the parameter text is a string, the line for letter in text[1]: doesn't make much sense to me since text[1] is a single character. What's the point of iterating over a one-letter string?
However, if text is a list of strings, then your function doesn't throw any exceptions, it simply returns the string that results from replacing in the first string (text[0]) all the letters of the second string (text[1]) by a blank space (" ").
The following examples show how remove_char works when its argument is a list of strings:
In [462]: remove_char(['spam', 'parrot', 'eggs'])
Out[462]: 's m'
In [463]: remove_char(['bar', 'baz', 'foo'])
Out[463]: ' r'
In [464]: remove_char(['CASE', 'sensitive'])
Out[464]: 'CASE'
Perhaps this is not the intended behaviour...
How can I write some text to the end of a line in a multiple-line string in python, without knowing slice numbers? Here's an example:
mystring="""
This is a string.
This is the second Line. #How to append to the end of this line, without slicing?
This is the third line."""
I hope I'm clear.
If the string is relatively small, I'd use str.split('\n') to break it into a list of strings. Then change the string you want, and the join the list:
l = mystr.split('\n')
l[2] += ' extra text'
mystr = '\n'.join(l)
Also, if you can identify uniquely how the line you want to append to ends, you can use replace. For instance, if the line ends with x, then you could do
mystr.replace('x\n', 'x extra extra stuff\n')
First of all, strings are immutable so you will have to build a new string. Use the method splitlines on mystring object (so that you don't have to explicitly specify the line-end char) and then join them into a new string however you wish.
>>> mystring = """
... a
... b
... c"""
>>> print mystring
a
b
c
>>> mystring_lines = mystring.splitlines()
>>> mystring_lines[2] += ' SPAM'
>>> print '\n'.join(mystring_lines)
a
b SPAM
c
In trying to capitalize a string at separators I encountered behavior I do not understand. Can someone please explain why the string s in reverted during the loop? Thanks.
s = 'these-three_words'
seperators = ('-','_')
for sep in seperators:
s = sep.join([i.capitalize() for i in s.split(sep)])
print s
print s
stdout:
These-Three_words
These-three_Words
These-three_Words
capitalize turns the first character uppercase and the rest of the string lowercase.
In the first iteration, it looks like this:
>>> [i.capitalize() for i in s.split('-')]
['These', 'Three_words']
In the second iteration, the strings are the separated into:
>>> [i for i in s.split('_')]
['These-Three', 'words']
So running capitalize on both will then turn the T in Three lowercase.
You could use title():
>>> s = 'these-three_words'
>>> print s.title()
These-Three_Words
str.capitalize capitalizes the first character and lowercases the remaining characters.
Capitalize() will return a copy of the string with only its first character capitalized. You could use this:
def cap(s):
return s[0].upper() + s[1:]