Find function in Python 3.x - python

When we have the following:
tweet2 = 'Want cheap snacks? Visit #cssu office in BA2283'
print(tweet2[tweet2.find('cheap')]) results in the output 'c' and I cant wrap my head around how it does this. I tried the visualizer and it didn't show anything. Could anyone please explain?

tweet2.find('cheap') returns the index at which the beginning of "cheap" is found, and when that index is used in tweet2[index], it returns the character at that index, which is "c"

It's because the find(str, string) method determines if str occurs in string, or in a substring of string and returns the position of first occurrence. So when you call tweet2.find('cheap') it will return the position that is the first occurs of cheap.

You should consider reading python documentation on string methods and lists
# define string variable tweet2
tweet2 = 'Want cheap snacks? Visit #cssu office in BA2283'
# find position of substring 'cheap', which is 5 (strings has 0-based indices in python
n = tweet2.find('cheap')
# print 5th element of string, which is 'c'
print(tweet2[n])

find returns an index, not a slice.
If you want the full string you can get it like so:
to_find = 'cheap'
ind = tweet2.find(to_find)
print(tweet2[ind:ind+len(to_find)])

Related

Efficient way to convert a list of one string to a string and perform split operation

I have a list which contains a string shown below. I have defined mylist in the global space as a string using "".
mylist = ""
mylist = ["1.22.43.45"]
I get an execution error stating that the split operation is not possible as it is being performed on a list rather than the string.
mylist.rsplit(".",1)[-1]
I tried to resolve it by using the following code:
str(mylist.rsplit(".",1)[-1]
Is this the best way to do it? The output I want is 45. I am splitting the string and accessing the last element. Any help is appreciated.
mylist=["1.22.43.45"]
newstring = mylist[0].rsplit(".",1)[-1]
First select the element in your list then split then choose the last element in the split
Just because you assigned mylist = "" first, doesn't mean it'll cast the list to a string. You've just reassigned the variable to point at a list instead of an empty string.
You can accomplish what you want using:
mylist = ["1.22.43.45"]
mylist[-1].rsplit('.', 1)[-1]
Which will get the last item from the list and try and perform a rsplit on it. Of course, this won't work if the list is empty, or if the last item in the list is not a string. You may want to wrap this in a try/except block to catch IndexError for example.
EDIT: Added the [-1] index to the end to grab the last list item from the split, since rsplit() returns a list, not a string. See DrBwts' answer
You can access the first element (the string, in your case) by the index operator []
mylist[0].rsplit(".", 1)[-1]

How to write a function to find positions of substring within a larger string without using the 'find' function?

I have just recently started using python and I am extremely new to python and coding in general and I'm in a class where we have been given the assignment to find a function in Python that takes two strings of DNA sequence (say string1 and string2) as input and returns a list of the position(s) where string2 is present as a substring of string1. And since we're supposed to be becoming familiar with how coding works, we can't use the "find" built-in function. I'm really confused on how to even start this problem. But this is what I have so far:
def linear(seq, sub):
positions = [0]
for i in range(len(sub)):
if seq[i:i+len(sub)] == sub:
positions[0]+=1
return( positions )
I get an error when I put this in but I should get out a list of the positions where the substring occurs. If someone can guide me in which direction I should be going, that would be really helpful.
As an example if the sequence is 'ATTCCATGGACCTAGTCAT' and the substring I want to find is 'CAT', then the output should be [5,17]
Unfortunately, it can't be [5,17] as indexing in python starts at 0, it should be [4,16]. You can use a for loop to go through the indexes till the last index minus the length of the substring plus 1 in order not to get out of range. Then you check if the slice of the string, which is the current index till the current index plus the length of the substring (if it is 'CAT' then you get every slice of the length of 3 of the string), is equal to the substring. If so then append the index to the index list.
def find(st,sub):
list_of_pos=[]
for i in range(len(st)-len(sub)+1):
if st[i:i+len(sub)]==sub:
list_of_pos.append(i)
return list_of_pos
You can make it more compact if you use list comprehension:
def find(st,sub):
return [i for i in range(len(st)-len(sub)+1) if st[i:i+len(sub)]==sub]

Error:string index out of range, defining a function

I'm practicing coding on codingbat.com since I'm a complete beginner in python, and here is one of the exercises:
Given a string, return a new string made of every other char starting with the first, so "Hello" yields "Hlo".
Here is my attempt at defining the function string_bits(str):
def string_bits(str):
char = 0
first = str[char]
for char in range(len(str)):
char += 2
every_other = str[char]
return (first + every_other)
Running the code gives an error. What's wrong with my code?
A different approach, with an explanation:
If you need to handle a sentence, where spaces would be included, you can do this using slicing. On a string slicing works as:
[start_of_string:end_of_string:jump_this_many_char_in_string]
So, you want to jump only every second letter, so you do:
[::2]
The first two are empty, because you just want to step every second character.
So, you can do this in one line, like this:
>>> " ".join(i[::2] for i in "Hello World".split())
'Hlo Wrd'
What just happened above, is we take our string, use split to make it a list. The split by default will split on a space, so we will have:
["Hello", "World"]
Then, what we will do from there, is using a comprehension, iterate through each item of the list, which will give us a word at a time, and from there we will perform the desired string manipulation per i[::2].
The comprehension is: (documentation)
i[::2] for i in "Hello World".split()
Finally, we call "".join (doc), which will now change our list back to a string, to finally give us the output:
"Hlo Wrd"
Check out the slicing section from the docs: https://docs.python.org/3/tutorial/introduction.html
The problem is that the char += 2 returns a value greater than len(str) as len(str)-1 (the range) + 2 is longer than the string. You could do:
def string_bits(string):
if len(string) == 2:
return string[0]
result = ''
for char in range(0,len(string),2):#range created value sin increments of two
result += string[char]
return result
A more succinct method would be:
def string_bits(string):
return string[::2]
You should avoid using 'str' as a variable name as it is a reserved word by Python.
Ok, for me:
You should not use str as a variable name as it is a python built-in function (replace str by my_str for example)
For example, 'Hello' length is 5, so 0 <= index <= 4. Here you are trying to access index 3+2=5 (when char = 3) in your for loop.
You can achieve what you want with the following code:
def string_bits(my_str):
result = ""
for char in range(0, len(my_str), 2):
result += my_str[char]
return result
The error you are getting means that you are trying to get the nth letter of a string that has less than n characters.
As another suggestion, strings are Sequence-types in Python, which means they have a lot of built-in functionalities for doing exactly what you're trying to do here. See Built-in Types - Python for more information, but know that sequence types support slicing - that is, selection of elements from the sequence.
So, you could slice your string like this:
def string_bits(input_string):
return input_string[::2]
Meaning "take my input_string from the start (:) to the end (:) and select every second (2) element"

Python Replace Character In List

I have a Python list that looks like the below:
list = ['|wwwwwwwwadawwwwwwwwi', '|oooooooocFcooooooooi']
I access the letter in the index I want by doing this:
list[y][x]
For example, list[1][10] returns F.
I would like to replace F with a value. Thus changing the string in the list.
I have tried list[y][x] = 'o' but it throws the error:
self.map[y][x] = 'o'
TypeError: 'str' object does not support item assignment
Can anybody help me out? Thanks.
As #Marcin says, Python strings are immutable. If you have a specific character/substring you want to replace, there is string.replace. You can also use lists of characters instead of strings, as described here if you want to support the functionality of changing one particular character.
If you want something like string.replace, but for an index rather than a substring, you can do something like:
def replaceOneCharInString(string, index, newString):
return string[:index] + newString + string[index+len(newString):]
You would need to do some length checking, though.
Edit: forgot string before the brackets on string[index+len(newString):]. Woops.
Since python strings are immutable, they cannot be modified. You need to make new ones. One way is as follows:
tmp_list = list(a_list[1])
tmp_list[10] = 'o' # simulates: list[1][10]='o'
new_str = ''.join(tmp_list)
#Gives |oooooooococooooooooi
# substitute the string in your list
a_list[1] = new_str
As marcin says, strings are immutable in Python so you can not assign to individual characters in an existing string. The reason you can index them is that thay are sequences. Thus
for c in "ABCDEF":
print(c)
Will work, and print each character of the string on a separate line.
To achieve what you want you need to build a new string.For example, here is a brute force approach to replacing a single character of a string
def replace_1(s, index, c)
return s[:index] + c + s[index+1:]
Which you can use thus:
self.map[y] = replace_1(self.map[y], x, 'o')
This will work because self.map is list, which is mutable by design.
Let use L to represent the "list" since list is a function in python
L= ['|wwwwwwwwadawwwwwwwwi', '|oooooooocFcooooooooi']
L[1]='|oooooooococooooooooi'
print(L)
Unfortunately changing a character from an object (in this case) is not supported. The proper way would be to remove the object and add a new string object.
Output
['|wwwwwwwwadawwwwwwwwi', '|oooooooococooooooooi']

Is there a python special character for a blank value?

I don't know how to ask this so I'm going to explain what I'm doing instead. I'm trying to search a list of lists with only 2 values. The first value I don't care about the second how ever I need to check and if it exsists I need the first value. Example
list = [[1,'text1'],[1,'text2'],[3,'text3'],[2,'text4']]
so basically I need to know if there is a character like % or ! that when used in find basically means any value. Link find(!,'text2') would get me the value of 1. (i know that wouldn't work like that). Ik I have the option of searching just the second value in lists but that's unecessary code if there is a special character as such.
There is no specific character or value for that, but you can either create your own sentinel object or you can use None for this. Just make sure to use is to detect it within your code.
# fmod.py
Any = object()
def find(first=Any, second=Any):
if first is Any:
...
...
import fmod
fmod.find(None, 'text2')
fmod.find(fmod.Any, 'text2')
You can do this with a list comprehension:
def findit(word, lst):
return [el[0] for el in lst if el[1] == word][0]
Try None value.
You can read more information about it here: Python 3 Constrants
When you say "the second how ever I need to check and if it exists I need the first value", I'm thinking you need to check if the second value is a) there (if the list has two elements) and b) of nonzero length (assuming they'll always be strings). This leads me to:
list_to_search = [[1,'text1'],[1,'text2'],[3,'text3'],[2,'text4'], [3], [4, '']]
firsts_with_seconds = [item[0] for item in list_to_search
if len(item) > 0 and len(item[1]) > 0]

Categories