Subtraction of one string values from another string values - python

I got two strings, called string1 and string2. Both consists of 6 different numbers.
What i would like to do in Python is to substract the values in string1 from the values in string2. How do I do this? I Guess this involves a for loop, since I only want to substract the first value in string1 from the first value in string2. And substract the second value from string1 from the second value in string2 etc.
So if string 1 got the numbers
2 5 8 9 6 3
and string 2 got the numbers
2 3 5 9 3 2
I want to take "string1" minus "string2" to get
0 2 3 0 3 1
Any suggestions?

You can achieve this with split(), zip(), and join():
" ".join([str(int(a) - int(b)) for a, b in zip(s1.split(), s2.split())])

Building on #pault answer, you can have the following variation (removed the calls to split(), added a conditional):
"".join([str(int(a) - int(b)) if a != ' ' else ' ' for a, b in zip(s1, s2)])
which is simply fancier way of doing:
" ".join([str(int(a) - int(b)) for a, b in zip(s1.replace(' ', ''), s2.replace(' ', ''))])
The latter might be more readable.

You can use regular expressions:
import re
s1 = '2 5 8 9 6 3'
s2 = '2 3 5 9 3 2'
new_string = ' '.join(str(a-b) for a, b in zip(map(int, re.findall('\d+', s1)), map(int, re.findall('\d+', s2))))
Output:
'0 2 3 0 3 1'

s1 = '2 5 8 9 6 3'
s2 = '2 3 5 9 3 2'
l1 = [int(x) for x in s1.split()]
l2 = [int(x) for x in s2.split()]
r1 = [v1 - v2 for v1, v2 in zip(l1, l2)]
.split() splits your string into a list based on where whitespace occurs (although you could provide it an argument to tell it to split on something else).
[int(x) for x in s1.split()] is a list comprehension. It's a one-line loop that does stuff for each value in a list (the split string). We need to convert the values in the split string into ints.
zip(l1, l2) takes the values in two lists and pairs them up. You'd need the lists to have the same number of elements for this to work (we do). From here, we use another list comprehension to pull out pairs of values and then take the difference.
edit (ty danihp): if you need the results to be a string, you can join the values in the list with ' '.join([str(x) for x in r1]) (this uses a space to separate elements in the list).

Step for step:
s1 = '2 5 8 9 6 3'
s2 = '2 3 5 9 3 2'
s3 = [int(x) for x in s1.split()] # split and convert to int
s4 = [int(x) for x in s2.split()] # split and convert to int
s5 = [] # result
for idx in range(0,len(s3)): # length are equal so this is ok
s5.append(s3[idx]-s4[idx]) # put into result
rv = " ".join([str(x) for x in s5]) # join result to string
print(s1)
print(s2)
print(s3)
print(s4)
print(s5)
print(rv)
Output:
2 5 8 9 6 3
2 3 5 9 3 2
[2, 5, 8, 9, 6, 3]
[2, 3, 5, 9, 3, 2]
[0, 2, 3, 0, 3, 1]
0 2 3 0 3 1

Since python is typed, you cannot subtact the strings: you have to convert each string to a list of integers and then subtract each one of the elements.
You can do this with only one loop:
s1 = '2 5 8 9 6 3'
s2 = '2 3 5 9 3 2'
list_diff = [int(x2) - int(x1) for x1, x2 in zip(s1.split(), s2.split())]
# or if you want the result as a string:
list_diff = [str(int(x1) - int(x2)) for x1, x2 in zip(s1.split(), s2.split())]
result = " ".join(list_diff)

Related

python print 3 strings of a list

I'm trying get the first 3 elements of a list.
1 a = "101.10.10.10"
2
3 b = "102.12.12.12"
4
5
6 asplit = a.split(".")
7 print("a - ")
8 print(asplit)
9
10 bsplit = b.split(".")
11 print("b - ")
12 print(bsplit)
13
14 print()
15 print()
16
17 print("---")
18 print (a[0], a[3])
when i'm using this code it returns
1 and .
i want to print
101 10 10
or
102 12 12
We can combine list comprehension, split() function, join() function and slicing to do that. At first, we split the string from dots. Then we create a list comprehension which will eliminate empty string. Then we join it, as a final step we use the [0:3] slice.
b = "102.12.12.12"
print(' '.join([x for x in b.split('.') if x != ''][0:3]))
In [1]: a = "101.10.10.10"
In [2]: " ".join(a.split(".")[:3])
Out[2]: '101 10 10'
In [3]: b = "102.12.12.12"
In [4]: " ".join(b.split(".")[:3])
Out[4]: '102 12 12'

Splitting string every 80 spaces

I have a string of 6400 numbers which I want to put into an 80x80 string format, for example
string1 = '1 2 3 4 5 6 7 8 9'
What I'm trying to do is this:
string2 = '''1 2 3
4 5 6
7 8 9'''
*the numbers are different lengths too
I have tried using split() but I don't know how to 'count' the amount of spaces and put it into one large string
You can split on space and iterate through it making chunks of given size:
string1 = '1 2 3 4 5 6 7 8 9'
size = 3
splits = string1.split()
print('\n'.join(' '.join(splits[j] for j in range(i, i+size)) for i in range(0, len(splits), size)))
# 1 2 3
# 4 5 6
# 7 8 9
Variable-length numbers? Just use regex.
import re
string1 = '1 22 333 4444 55555 666666 77777777 888888888 9999999999'
string2 = '\n'.join(re.findall('((?:\S+ ){2}\S+)', string1))
The (?:) makes a group you can repeat but doesn't capture it in the match, which makes the direct join possible. Without it, you'd get tuples.
A re.sub would also work.
string2 = re.sub('((\S+ ){2}\S+) ', lambda m: m.group()+'\n', string1)
You would use a {79} instead of the {2} of course, which repeats the '\S+ ' pattern (one or more non-whitespace characters followed by a space) so you don't have to write it out.
You could do this by slicing the string by a set chunk size
# Print a new line every 6 characters
# Change this as needed
chunk_size = 6
# The string to split
s = '1 2 3 4 5 6 7 8 9'
# Iterate over a range of numbers 0 to the length of the string
# with a step size of `chunk_size`
# With `chunk_size` as 6, the range will look like
# [0, 6, 12]
for i in range(0, len(s), chunk_size):
# Slice the string from the current index
# to the current index plus the chunk size
# ie: [0:6], [6:12], [12:18]
print(s[i:i+chunk_size])
print()
# To do this with list comprehension
s2 = "\n".join(s[i:i+chunk_size] for i in range(0, len(s), chunk_size))
print(s2)
# Ouptut:
# 1 2 3
# 4 5 6
# 7 8 9
Or if you have variable length numbers, do as Austin said, and apply the same concept on a split version of the string
chunk_size = 3
s = '10 20 30 4 5 6 7 8 9'.split()
for i in range(0, len(s), chunk_size):
print(" ".join(s[i:i+chunk_size]))
print()
s2 = "\n".join(" ".join(s[i:i+chunk_size]) for i in range(0, len(s), chunk_size))
print(s2)
# Output:
# 10 20 30
# 4 5 6
# 7 8 9

Enumerating Ascii characters using range and enumerate

I'm new to this enumerate command and I'm not sure if I'm supposed to use it like this, what I want to do is to enumerate the ASCII characters from 0 - 129, and what I get is '1' before each character.
for x in range(129):
xxx = chr(x)
z = list(xxx)
for i, a in enumerate(z, 1):
print(i, a)
random text output:
1 .
1 /
1 0
1 1
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
You are looping over a list with a single character in it:
>>> xxx = chr(65)
>>> xxx
'A'
>>> list(xxx)
['A']
>>> len(list(xxx))
1
You then loop over the enumerate() result for that single character, so yes, you only get 1.
You repeat that inner loop for each value of x, so you do get it 129 times. It is your outer for x in range(129) loop that makes the 1s repeat.
You'd use enumerate() for the outer loop, and there's no point in turning your single character into a list each time:
for i, x in enumerate(range(129)):
xxx = chr(x)
print(i, xxx)
Note that x is already an increasing integer number however. enumerate() is really just overkill here. Just print x + 1 for the same number:
for x in range(129):
xxx = chr(x)
print(x + 1, xxx)

Recursive Pascals Triangle Layout

So i've managed to get Pascals Triangle to print successfully in terms of what numbers are printed, however, i can't get the formatting correct using:
n = int(input("Enter value of n: "))
def printPascal(n):
if n <= 0: #must be positive int
return "N must be greater than 0"
elif n == 1: #first row is 1, so if only 1 line is wanted, output always 1
return [[1]]
else:
next_row = [1] #each line begins with 1
outcome = printPascal(n-1)
prev_row = outcome[-1]
for i in range(len(prev_row)-1): #-1 from length as using index
next_row.append(prev_row[i] + prev_row[i+1])
next_row += [1]
outcome.append(next_row) #add result of next row to outcome to print
return outcome
print(printPascal(n))
this prints as:
Enter value of n: 6
[[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1], [1, 5, 10, 10, 5, 1]
which is correct, however i want it to be formatted as a right angle triangle such as:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
my issue is, i'm new to this language and cannot work out where to put the splits and such in my code to be able to get it to print as this.
Any help or nudge in the right direction would be very much appreciated.
Thanks.
You want to use the str.join() function, which prints out all elements in a list separated by a string:
>>> L = printPascal(6)
>>> for row in L:
... print ' '.join(map(str, row))
...
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
' '.join(list) means you're printing out every element in a list separated by a space (' ').
However, every element in the list needs to be a string in order for the join function to work. Yours are integers. To fix this, I've changed all the integers to strings by doing map(str, row). This is equivalent to:
new_list = []
for item in row:
new_list.append(str(item))
Or as a list comprehension:
[str(item) for item in row]

Integer list join using string.format

As Joining a list that has Integer values with Python, the integer list can be joined by converting str and then joining them.
BTW, I want to get foo bar 10 0 1 2 3 4 5 6 7 8 9 where several data are first(foo, bar), then the size of list 10 and elements follows.
I used string.format as
x = range(10)
out = '{} {} {} {}'.format('foo', 'bar', len(x), x)
out will be foo bar 10 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
To solve problem I can rewrite the code as
out = '{} {} {} '.format('foo', 'bar', len(x)) + ' '.join([str(i) for i in x])
It looks inconsistent (mixed string.format and join). I tried
slot = ' {}' * len(x)
out = ('{} {} {}' + slot).format('foo', 'bar', len(x), *x)
It still unattractive I think. Is there a way to join integer list using string.format only?
Since you favor attractiveness, want to use only one line and with format only, you can do
'{} {} {}{}'.format('foo', 'bar', len(x), ' {}' * len(x)).format(*x)
# foo bar 10 0 1 2 3 4 5 6 7 8 9
I might be missing the point of your question, but you could simply extend the approach you link to as follows:
>>> x = range(10)
>>> out = " ".join(map(str, ["foo", "bar", len(x)] + x))
>>> out
'foo bar 10 0 1 2 3 4 5 6 7 8 9'
You can simply use the print function for this:
>>> from __future__ import print_function #Required for Python 2
>>> print('foo', 'bar', len(x), *x)
foo bar 10 0 1 2 3 4 5 6 7 8 9

Categories

Resources