regarding list object's attributes - python

While I am writing this code lst=list(map(int,input().split().strip())) then I am getting an AttributeError 'list' object has no attribute strip
But it is working when I remove the strip() method.
My question is that list object also has no attribute split. So in this case (lst=list(map(int,input().split())) why it is not giving any error and why it is giving error in case of strip() method?

Before you read the rest of the answer: you shouldn't have to strip() after you call split() because split() will consider multiple whitespace characters as a single delimiter and automatically remove the extra whitespace. For example, this snippet evaluates to True:
s1 = "1 2 3"
s2 = "1 2 3"
s3 = " 1 2 3 "
s1.split() == s2.split() == s3.split()
split() and strip() are both attributes of string objects!
When you're confused by code that's been stuffed into one line, it often helps to unravel that code out over multiple lines to understand what it's doing
Your line of code can be unraveled like so:
user_input_str = input()
split_input_list = user_input_str.split()
stripped_input = split_input_list.strip() ### ERROR!!!
lst = list(map(int, stripped_input))
Clearly, you tried to access the strip() method of a list object, and you know that doesn't exist.
In your second example, you do
user_input_str = input()
split_input_list = user_input_str.split()
lst = list(map(int, split_input_list))
Which works perfectly fine because you don't try to access strip() on a list object
Now to fix this, you need to change the order of operations: first, you get your input. Next, strip it. This gives you back a string. Then, split this stripped string.
user_input_str = input()
stripped_input_str = user_input_str.strip() ### No error now!
split_input_list = stripped_input_str.split()
lst = list(map(int, split_input_list))
#or in one line:
lst = list(map(int, input().strip().split()))
Or, if you want to strip each element of the split input list, you will need to map the strip() function to split_input_list like so:
user_input_str = input()
split_input_list = user_input_str.split()
stripped_input_list = list(map(str.strip, split_input_list))
lst = list(map(int, stripped_input_list))
#or in one line
lst = list(map(int, map(str.strip, input().split())))
# or, create a function that calls strip and then converts to int, and map to it
def stripint(value):
return int(value.strip())
lst = list(map(stripint, input().split()))

Related

python string split slice and into a list

I have a string for example "streemlocalbbv"
and I have my_function that takes this string and a string that I want to find ("loc") in the original string. And what I want to get returned is this;
my_function("streemlocalbbv", "loc")
output = ["streem","loc","albbv"]
what I did so far is
def find_split(string,find_word):
length = len(string)
find_word_start_index = string.find(find_word)
find_word_end_index = find_word_start_index + len(find_word)
string[find_word_start_index:find_word_end_index]
a = string[0:find_word_start_index]
b = string[find_word_start_index:find_word_end_index]
c = string[find_word_end_index:length]
return [a,b,c]
Trying to find the index of the string I am looking for in the original string, and then split the original string. But from here I am not sure how should I do it.
You can use str.partition which does exactly what you want:
>>> "streemlocalbbv".partition("loc")
('streem', 'loc', 'albbv')
Use the split function:
def find_split(string,find_word):
ends = string.split(find_word)
return [ends[0], find_word, ends[1]]
Use the split, index and insert function to solve this
def my_function(word,split_by):
l = word.split(split_by)
l.insert(l.index(word[:word.find(split_by)])+1,split_by)
return l
print(my_function("streemlocalbbv", "loc"))
#['str', 'eem', 'localbbv']

TypeError: list indices must be integers or slices, not re.Pattern

I am trying to extract data from text using regular expressions. I want to loop through the regular expression 'options' and then write the outcome to a specific list.
I think that I may not be writing my loop, and referencing the lists correctly. I get an error on line 27 stating: TypeError: list indices must be integers or slices, not re.Pattern. I have tried to put the regexlist into range(), but i then get this error: TypeError: 'list' object cannot be interpreted as an integer on line 18 this time. I'm not sure on how to get around this?
Please see my code below:
import re
regexcode0 = re.compile(r'Test 0')
regexcode1 = re.compile(r'Test 1')
regexcode2 = re.compile(r'Test 2')
results_Test0 = []
results_Test1 = []
results_Test2 = []
allResults = [results_Test0, results_Test1, results_Test2]
regexlist = [regexcode0, regexcode1, regexcode2]
textBody = 'Hi there, Test 2 was a failure'
def text_extract(text):
for i in regexlist:
match = re.search(i, text)
if match:
matchObj = match.group()
allResults[i].append(matchObj)
if not match:
allResults[i].append('No Solution')
return allResults
print(text_extract(textBody))
I want the results to look like this:
results_Test0 = ['No Solution']
results_Test1 = ['No Solution']
results_Test2 = ['Test 2']
The type of results_Testn is list. The syntax of list[index] requires an integer to indicate a specific postition in the list. You are attempting to use i as an index, and its type is not integer, so that results in the error. If you want an integer for each iteration of the for loop, you can use the enumerate function:
for index, i in enumerate(regexlist):
#do something
In this example, i represents the re pattern and index is the number representing its position in the list, so you can use allresults[index] to save the result.

function call the convert a list is alpha characters to numeric

I am trying a manual implementation of the Soundex Algorithm and this requires converting alpha text characters to numeric text characters. I have defined the following function:
import re
def sub_pattern(text):
sub = [str(i) for i in range(1,4)]
string = text
abc = re.compile('[abc]')
xyz = re.compile('[xyz]')
encode = [abc, xyz]
encode_iter = iter(encode)
alpha_search = re.compile('[a-zA-Z]')
for i in sub:
if alpha_search.search(string):
pattern = next(encode_iter)
string = pattern.sub(i, string)
else:
return(string)
This function will encode abc characters to 1 and xyz characters to 2. However, it only works for a single string and I need to pass a list of strings to the function. I've gotten the results I want using:
list(map(sub_pattern, ['aab', 'axy', 'bzz']
But I want to be able to pass the list to the function directly. I've tried this with no success as it ends only returning the first string from the list.
def sub_pattern(text_list):
all_encoded = []
sub = [str(i) for i in range(1,4)]
abc = re.compile('[abc]')
xyz = re.compile('[xyz]')
encode = [abc, xyz]
encode_iter = iter(encode)
alpha_search = re.compile('[a-zA-Z]')
for string in text_list:
for i in sub:
if alpha_search.search(string):
pattern = next(encode_iter)
string = pattern.sub(i, string)
else:
all_encoded.append(string)
A couple things to note:
Because I am implementing the Soundex Algorithm, the order of the text when I encode it matters. I would prefer to update the string character at its orginal index to avoid having to reorganize it afterwards. In other words, you can't do any sorting to the string...I've created the iterator to incrementally update the string and it only grabs the next regex pattern if all the characters have not already been converted.
This function will be a part of two custom classes that I am creating. Both will call the __iter__ method so that I can created the iterable. That's why I use the iter() function to create an iterable because it will create a new instance if the iterator automatically.
I know this may seem like a trivial issue relative to what I'm doing, but I'm stuck.
Thank you in advance.
How about using your own function recursively? You get to keep the original exactly as it is, in case you needed it:
import re
def sub_pattern(text):
if isinstance(text, str):
sub = [str(i) for i in range(1,4)]
string = text
abc = re.compile('[abc]')
xyz = re.compile('[xyz]')
encode = [abc, xyz]
encode_iter = iter(encode)
alpha_search = re.compile('[a-zA-Z]')
for i in sub:
if alpha_search.search(string):
pattern = next(encode_iter)
string = pattern.sub(i, string)
else:
return(string)
else:
return([sub_pattern(t) for t in text])
print(list(map(sub_pattern, ['aab', 'axy', 'bzz']))) # old version still works
print(sub_pattern(['aab', 'axy', 'bzz'])) # new version yields the same result
Should a reader don't know what recursively means: calling a function from within itself.
It is allowed because each function call creates its own
scope,
it can be useful when you can solve a problem by performing a simple operation multiple times, or can't predict in advance how many times you need to perform it to reach your solution, e.g. when you need to unpack nested structures
it is defined by choosing a base case (the solution), and call the function in all other cases until you reach your base case.
I assume the issue with your example was, that once you traversed the iterator, you ran into StopIteration for the next string.
I'm not sure this is what you want, but I would create a new iterator for each string, since you have to be able to traverse over all of it for every new item. I tweaked some variable names that may cause confusion, too (string and sub). See comments for changes:
def sub_pattern(text_list):
all_encoded = []
digits = [str(i) for i in range(1,4)]
abc = re.compile('[abc]')
xyz = re.compile('[xyz]')
encode = [abc, xyz]
alpha_search = re.compile('[a-zA-Z]')
for item in text_list:
# Create new iterator for each string.
encode_iter = iter(encode)
for i in digits:
if alpha_search.search(item):
pattern = next(encode_iter)
item = pattern.sub(i, item)
else:
all_encoded.append(item)
# You likely want appending to end once no more letters can be found.
break
# Return encoded texts.
return all_encoded
Test:
print(sub_pattern(['aab', 'axy', 'bzz'])) # Output: ['111', '122', '122']

Python Joining List and adding and removing characters

I have a list i need to .join as string and append characters
my_list = ['3.3.3.3', '2.2.2.3', '2.2.2.2']
my_list.append(')"')
my_list.insert(0,'"(')
hostman = '|'.join('{0}'.format(w) for w in my_list)
#my_list.pop()
print(hostman)
print(my_list)
My output = "(|3.3.3.3|2.2.2.3|2.2.2.2|)"
I need the output to be = "(3.3.3.3|2.2.2.3|2.2.2.2)"
how can i strip the first and last | from the string
You are making it harder than it needs to be. You can just use join() directly with the list:
my_list = ['3.3.3.3', '2.2.2.3', '2.2.2.2']
s = '"(' + '|'.join(my_list) + ')"'
# s is "(3.3.3.3|2.2.2.3|2.2.2.2)"
# with quotes as part of the string
or if you prefer format:
s = '"({})"'.format('|'.join(my_list))
Try this :
hostman = "("+"|".join(my_list)+")"
OUTPUT :
'(3.3.3.3|2.2.2.3|2.2.2.2)'

Remove comma and change string to float

I want to find "money" in a file and change the string to float , for example, I use regular expression to find "$33,326" and would like to change to [33326.0, "$"] (i.e., remove comma, $ sign and change to float). I wrote the following function but it gives me an error
import locale,re
def currencyToFloat(x):
empty = []
reNum = re.compile(r"""(?P<prefix>\$)?(?P<number>[.,0-9]+)(?P<suffix>\s+[a-zA-Z]+)?""")
new = reNum.findall(x)
for i in new:
i[1].replace(",", "")
float(i[1])
empty.append(i[1])
empty.append(i[0])
return empty
print currencyToFloat("$33,326")
Can you help me debug my code?
money = "$33,326"
money_list = [float("".join(money[1:].split(","))), "$"]
print(money_list)
OUTPUT
[33326.0, '$']
When you do
float(i[1])
you are not modifying anything. You should store the result in some variable, like:
temp = ...
But to cast to float your number have to have a dot, not a comma, so you can do:
temp = i[1].replace(",", ".")
and then cast it to float and append to the list:
empty.append(float(temp))
Note:
Something important you should know is that when you loop through a list, like
for i in new:
i is a copy of each element, so if you modify it, no changes will be done in the list new. To modify the list you can iterate over the indices:
for i in range(len(new)):
new[i] = ...
You can use str.translate()
>>>money= "$333,26"
>>>float(money.translate(None, ",$"))
33326.0
With Python 3 you can use str.maketrans with str.translate:
money = "$33,326"
print('money: {}'.format(float(money.translate(str.maketrans('', '', ",$")))))
Output: money: 33326.0

Categories