How to input negative numbers into a list - python

I require some help since whenever I input a negative number the list it interprets it as a separate element so once it gets to sorting it puts all the negative symbols at the beginning. The end goal of the code is to sort 2 merged lists without using the default sort functions. Also if there is a better way to get rid of spaces in a list I would appreciate it, since at the moment I have to convert the list to a string and replace/strip the extra elements that the spaces cause.
list1 = list(input())
list2 = list(input())
mergelist = list1 + list2
print(mergelist)
def bubble_sort(X):
nums = list(X)
for i in range(len(X)):
for j in range(i+1, len(X)):
if X[j] < X[i]:
X[j], X[i] = X[i], X[j]
return X
mergelist = bubble_sort(mergelist)
strmergelist = str(mergelist)
strmergelist = strmergelist.replace("'", '')
strmergelist = strmergelist.replace(",", '')
strmergelist = strmergelist.strip('[]')
strmergelist = strmergelist.strip()
print(strmergelist)
The output for lists with no negatives is:
1 2 3 4 4 5 5
However with negatives it becomes:
- - - - 1 2 3 3 4 4 5
and my first print function to just check the merging of the lists looks like this when I input any negatives (ignore the spaces since I attempt to remove them later):
['1', ' ', '-', '2', ' ', '3', '3', ' ', '-', '4', ' ', '-', '4', ' ', '-', '5']

list() doesn't parse a string to a list of integers, it turns an iterable of items into a list of items.
To read a list from the console, try something like:
def read_list():
"""
read a list of integers from stdin
"""
return list(map(int, input().split()))
list1 = read_list()
list2 = read_list()
input.split() reads one line of user input and will separate it by whitespace - basically to words.
int() can convert a string to an integer.
map(int, ...) returns an iterable which applies int() to each "word" of the user input.
The final call to list() will turn the iterable to a list.
This should handle negative numbers as well.
Additionally, I see that you want to print the resulting list without extra character. I recommend this:
print(' '.join(mergelist))

Related

How to perform operation on specific elements of a list? [duplicate]

This question already has answers here:
modify list elements on a condition
(3 answers)
Closed last year.
So, I want the odd numbers of the list to be multiplied by two and form a new list with the same index value but no other changes in the initial list,
for example i is the initial list and o is the output i want
i=['0','7','2','3','4']
o=['0','14','2,'6','4']
here's the code I tried:
list=["1","3","7"]
for num in list:
if num%2!=0:
num*2
print(list)
here's the error I get:
PS C:\Users\suhas\Desktop\sujan> & C:/Users/suhas/AppData/Local/Programs/Python/Python39/python.exe c:/Users/suhas/Desktop/sujan/user_testing.py
Traceback (most recent call last):
File "c:\Users\suhas\Desktop\sujan\user_testing.py", line 5, in <module>
if num%2!=0:
TypeError: not all arguments converted during string formatting
ls = ['1', '2', '3']
for i, el in enumerate(ls):
if int(el) % 2:
ls[i] = str(int(el)*2)
print(ls)
# prints ['2', '2', '6']
If you intend to not mutate the input list and create a new list for the results:
ls = ['1', '2', '3']
res = []
for el in ls:
if int(el) % 2:
res.append(str(int(el)*2))
else:
res.append(el)
print(res)
# prints ['2', '2', '6']
If the input list were only integers you wouldn't need to convert the elements to integers and back to strings, of course:
ls = [1, 2, 3]
for i, el in enumerate(ls):
if el % 2:
ls[i] = el*2
print(ls)
# prints [2, 2, 6]
Please avoid naming your lists list. This shadows the list type of python and can create a lot of confusion and subtle bugs later on.
Your error comes from the comparison if num%2!=0: where num is a str-type and 0 is an integer. To check this you can use the type function, returning what type your variable num is;
list=["1","3","7"]
for num in list:
print(type(num))
if num%2!=0:
num*2
print(list)
instead of looping through the list and saving each element as a variable, you want to iterate through a range with the length of your list. By doing so you can use the number in the range to access the index of each element of the list instead and updating the lists element if your criteria is met;
list = ['0','7','2','3','4']
# wanted output ['0','14','2','6','4']
for i in range(len(list)):
num = int(list[i])
if num%2 != 0:
list[i] = num*2
print(list)
Read some about loops and lists to get the syntax right for next try :)
w3school Python - Loop Lists
The below approach uses a list comprehension to achieve the desired list. Here, if we consider in_list as input list then no. inside list is stored as a string so while iterating over the list to check whether no. is odd or even first no. needs to be converted to int and then it is checked with % operator if it is even then it's multiplied with 2 and then result is converted back to string as the output requirement is a list of numbers stored as a string
in_list=['0','7','2','3','4']
output = [i if (int(i)%2)==0 else str(int(i)*2) for i in in_list ]
print(output)
Example is a little misleading here. If we consider odd indices then
o=[int(i[x])*2 if x%2==1 else int(i[x]) for x in range(len(i))]
If we consider numbers themselves
o= [str(int(x)*2) if int(x)%2!=0 else x for x in i]

Common substring in list of strings

i encountered a problem while trying to solve a problem where given some strings and their lengths, you need to find their common substring. My code for the part where it loops through the list and then each through each word in it is this:
num_of_cases = int(input())
for i in range(1, num_of_cases+1):
if __name__ == '__main__':
len_of_str = list(map(int, input().split()))
len_of_virus = int(input())
strings = []
def string(strings, len_of_str):
len_of_list = len(len_of_str)
for i in range(1, len_of_list+1):
strings.append(input())
lst_of_subs = []
virus_index = []
def substr(strings, len_of_virus):
for word in strings:
for i in range(len(len_of_str)):
leng = word[i:len_of_virus]
lst_of_subs.append(leng)
virus_index.append(i)
print(string(strings, len_of_str))
print(substr(strings, len_of_virus))
And it prints the following given the strings: ananasso, associazione, tassonomia, massone
['anan', 'nan', 'an', 'n', 'asso', 'sso', 'so', 'o', 'tass', 'ass', 'ss', 's', 'mass', 'ass', 'ss', 's']
It seems that the end index doesn't increase, although i tried it by writing len_of_virus += 1 at the end of the loop.
sample input:
1
8 12 10 7
4
ananasso
associazione
tassonomia
massone
where the 1st letter is the number of cases, the second line is the name of the strings, 3rd is the length of the virus(the common substring), and then there are the given strings that i should loop through.
expected output:
Case #1: 4 0 1 1
where the four numbers are the starting indexes of the common substring.(i dont think that code for printing cares us for this particular problem)
What should i do? Please help!!
The problem, beside defining functions in odd places and using said function to get side effect in ways that aren't really encourage, is here:
for i in range(len(len_of_str)):
leng = word[i:len_of_virus]
i constantly increase in each iteration, but len_of_virus stay the same, so you are effectively doing
word[0:4] #when len_of_virus=4
word[1:4]
word[2:4]
word[3:4]
...
that is where the 'anan', 'nan', 'an', 'n', come from the first word "ananasso", and the same for the other
>>> word="ananasso"
>>> len_of_virus = 4
>>> for i in range(len(word)):
word[i:len_of_virus]
'anan'
'nan'
'an'
'n'
''
''
''
''
>>>
you can fix it moving the upper end by i, but that leave with the same problem in the other end
>>> for i in range(len(word)):
word[i:len_of_virus+i]
'anan'
'nana'
'anas'
'nass'
'asso'
'sso'
'so'
'o'
>>>
so some simple adjustments in the range and problem solve:
>>> for i in range(len(word)-len_of_virus+1):
word[i:len_of_virus+i]
'anan'
'nana'
'anas'
'nass'
'asso'
>>>
Now that the substring part is done, the rest is also easy
>>> def substring(text,size):
return [text[i:i+size] for i in range(len(text)-size+1)]
>>> def find_common(lst_text,size):
subs = [set(substring(x,size)) for x in lst_text]
return set.intersection(*subs)
>>> test="""ananasso
associazione
tassonomia
massone""".split()
>>> find_common(test,4)
{'asso'}
>>>
To find the common part to all the strings in our list we can use a set, first we put all the substring of a given word into a set and finally we intersect them all.
the rest is just printing it to your liking
>>> virus = find_common(test,4).pop()
>>> print("case 1:",*[x.index(virus) for x in test])
case 1: 4 0 1 1
>>>
First extract all the substrings of the give size from the shortest string. Then select the first of these substrings that is present in all of the strings. Finally output the position of this common substring in each of the strings:
def commonSubs(strings,size):
base = min(strings,key=len) # shortest string
subs = [base[i:i+size] for i in range(len(base)-size+1)] # all substrings
cs = next(ss for ss in subs if all(ss in s for s in strings)) # first common
return [s.index(cs) for s in strings] # indexes of common substring
output:
S = ["ananasso", "associazione", "tassonomia", "massone"]
print(commonSubs(S,4))
[4, 0, 1, 1]
You could also use a recursive approach:
def commonSubs(strings,size,i=0):
sub = strings[0][i:i+size]
if all(sub in s for s in strings):
return [s.index(sub) for s in strings]
return commonSubs(strings,size,i+1)
from suffix_trees import STree
STree.STree(["come have some apple pies",
'apple pie available',
'i love apple pie haha']).lcs()
the most simple way is use STree

How to delete spaces in printing the list?

def lexemize_Ari_Exp():
arithmeticExpression = input("Write an Arithmetic Expression: ")
list_Of_Arit_Exp = []
for x in arithmeticExpression:
list_Of_Arit_Exp.append(x)
print(list_Of_Arit_Exp)
lexemize_Ari_Exp()
#Input: x + 1
#Output: ['x', ' ', '+', ' ', '1']
If each element of the expression is divided by a space you can simply use the split() function:
def lexemize_Ari_Exp():
arithmeticExpression = input("Write an Arithmetic Expression: ")
list_Of_Arit_Exp = arithmeticExpression.split()
print(list_Of_Arit_Exp)
lexemize_Ari_Exp()
Example of output:
Write an Arithmetic Expression: x + 1
['x', '+', '1']
You can simply add an if statement like this:
for x in arithmeticExpression:
if not x == ' ':
list_Of_Arit_Exp.append(x)
This is because your for loop iterates on every single character of the input string, and x just represents the character in each iteration.
def remove (list, toRemove):
for i in range (0, list.count (toRemove)):
list.pop (list.index (toRemove))
return list
Use this function to remove the elements you want from a list
list = [0, 1, 0]
print (remove (list, 0))#Remove all the 0 from the list
Works with every type (int, float, string...)

Why isn't my List populating properly? (Python)

I'm trying to populate my list with numbers from 1 to and including 100.
However, the list won't populate as such. If you run the code you will see that I'm populating my list with single characters of numbers, so when I get into double digits... Things don't go so well.
Please, if you'd change my approach in anyway, let me know. I will be very grateful to say the least.
Here's my code:
myList = []
i =0
while len(myList) < 100:
i += 1
myList += str(i)
print (myList)
myList = []
i =0
while len(myList) < 100:
i += 1
myList += [str(i)] # or just use myList.append(i)
print (myList)
What happening in your case is when you do myList += str(i) what you are adding to list is not single value but instead array of characters.
Let me explain it with example.
>>> lst = []
>>> lst += str(123)
>>> lst
['1', '2', '3']
>>> lst += [str(123)]
>>> lst
['1', '2', '3', '123']
As you can see str(123) will be converted to iterable list ['1', '2', '3'] first then it will be added to list.
But in second case your right hand side [str(123)] is already a list so. Python will just add one element to your list.
PS: It's suggested to use the append method instead of += operator for better performance. As in += operator python needs to create a whole new list and iterate it for just one element.
Use a basic list comprehension with range:
myList = [ str(i) for i in range(1,101) ]
The argument is 101 so it includes 100:
The given end point is never part of the generated sequence ...
(from that link)
myList = []
i =0
while len(myList) < 100:
i += 1
myList.append(str(i))
print (myList)
Just use myList.append instead of += myList.

Split an element at whitespace in python 2

I have a text dump of letters and numbers, and I want to filter out only valid credit card numbers (for class, I swear). I used
for item in content:
nums.append(re.sub('[^0-9]', ' ', item))
to take out everything that isn't a number, so I have a list of elements that are numbers with white space in the middle. If I don't turn the non-int characters into spaces, the numbers end up concatenated so the lengths are wrong. I want to split each element into a new element at the whitespace.
Here's a screenshot of part of the Sample output, since I can't copy it without python turning every group of multiple spaces into a single space: https://gyazo.com/4db8b8b78be428c6b9ad7e2c552454af
I want to make a new element every time there is one or more spaces. I tried:
for item in nums:
for char in item:
char.split()
and
for item in nums:
item.split()
but that ended up not changing anything.
split doesn't mutate the string but returns a list of strings instead. If you call it without storing the result as in your example it won't do anything good. Just store the result of split to new list:
>>> nums = ['1231 34 42 432', '12 345345 7686', '234234 45646 435']
>>> result = []
>>> for item in nums:
... result.extend(item.split())
...
>>> result
['1231', '34', '42', '432', '12', '345345', '7686', '234234', '45646', '435']
Alternatively you could use list comprehension to do the above on one line:
>>> [x for item in nums for x in item.split()]
['1231', '34', '42', '432', '12', '345345', '7686', '234234', '45646', '435']

Categories