Joining elements in a list without the join command - python

I need to join the elements in a list without using the join command, so if for example I have the list:
[12,4,15,11]
The output should be:
1241511
Here is my code so far:
def lists(list1):
answer = 0
h = len(list1)
while list1 != []:
answer = answer + list1[0] * 10 ** h
h = h - 1
list1.pop(0)
print(answer)
But, in the end, the answer ends up being 125610 which is clearly wrong.
I think the logic is OK, but I can't find the problem?

If you just want to print the number rather than return an actual int:
>>> a = [12,4,15,11]
>>> print(*a, sep='')
1241511

You could just convert each element to a string, add them, and then convert back to an int:
def lists(list1):
answer=''
for number in list1:
answer+=str(number)
print(int(answer))
lists([12,4,15,11])
>>>
1241511

s = ""
for x in map(str, x):
s += x
print(s)
1241511

There can be few more options like
Option1
>>> lst=[12,4,15,11]
>>> str(lst).translate(None, '[,] ')
'1241511'
Option 2
>>> join = lambda e: str(e[0]) + join(e[1:]) if e else ""
>>> join(lst)
'1241511'
Option 3
>>> ("{}"*len(lst)).format(*lst)
'1241511'
Option 4
>>> reduce(lambda a,b:a+b,map(str,lst))
'1241511'

a numeric solution, using your code
import math
def numdig(n):
#only positive numbers
if n > 0:
return int(math.log10(n))+1
else:
return 1
def lists(list1):
answer = 0
h = 0
while list1 != []:
answer = answer * 10 ** h + list1[0]
list1.pop(0)
if list1 != []:
h = numdig(list1[0])
print(answer)
lists([12,4,15,11])

You may try map and reduce with lambda like this:
def without_join(alist):
try:
return int(reduce(lambda a,b: a + b, map(str, alist)))
except ValueError, error:
print error
return None
print without_join([12,4,15,11])

Here's an entirely numerical solution, playing off of your notion of messing with powers of 10. You were on the right track, but your implementation assumed all values were 1 digit long.
import math
def lists(list1):
b = 0
foo = 0
for item in reversed(list1):
b += item*(10**foo)
foo += int(math.floor(math.log10(item))) + 1
return b
a = [12, 4, 15, 11]
print lists(a)
This returns 1241511, as requested.
All I'm doing here is looping through the list in reverse order and keeping track of how many digits to the left I need to shift each value. This allows integers with an arbitrary number of digits.

list_name_of_program = [a,b,c,d,e,f]
program = ""
for pro in list_name_of_program:
program += str(pro)
program += "," # you can use seprator a space " " or different
print(program[:-1])
Output:
'a,b,c,d,e,f'

Related

Extracting number from alphanumeric string and adding them

Given string str containing alphanumeric characters. The task is to calculate the sum of all the numbers present in the string.
Example 1:
Input:
str = 1abc23
Output: 24
Explanation: 1 and 23 are numbers in the
a string which is added to get the sum as
24.
Example 2:
Input:
str = geeks4geeks
Output: 4
Explanation: 4 is the only number, so the
the sum is 4.
I broke down the problem into smaller parts, for first I just want to extract the numbers.
s = "a12bc3d"
number = ""
for i in range(0, len(s)):
if s[i].isdigit():
n=0
number = number + s[i]
while s[i].isdigit():
n = n+1
if s[i + n].isdigit():
number = number + s[i+n] + " "
else:
break
i = i + n + 1
else:
continue
print(number)
my output from the above code is 12 23 but it should be 12 3, as the for loop is starting from the initial point making 2 coming twice, I have tried to move the for loop forward by updating i = i + n + 1 but it's not working out like that.
It will be great if someone gives me a direction, any help is really appreciated.
A slightly simpler approach with regex:
import re
numbers_sum = sum(int(match) for match in re.findall(r'(\d+)', s))
Use itertools.groupby to break the string into groups of digits and not-digits; then convert the digit groups to int and sum them:
>>> from itertools import groupby
>>> def sum_numbers(s: str) -> int:
... return sum(int(''.join(g)) for d, g in groupby(s, str.isdigit) if d)
...
>>> sum_numbers("1abc23")
24
>>> sum_numbers("geeks4geeks")
4
you can use regex.
import re
s='a12bc3d'
sections = re.split('(\d+)',s)
numeric_sections = [int(x) for x in sections if x.isdigit()]
sum_ = sum(numeric_sections)
print(sum_)
I appreciate the solutions with regex and group-by. And I got the solution using logic as well.
`s = "4a7312cfh86"
slist = [i for i in s]
nlist = []
for i in range(len(slist)):
if slist[i].isdigit() and (i != (len(slist) - 1)):
if not slist[i + 1].isdigit():
nlist.append(slist[i])
else:
slist[i + 1] = slist[i] + slist[i + 1]
elif slist[i].isdigit() and (i == (len(slist) - 1)):
nlist.append(slist[i])
def addingElement(arr):
if len(arr) == 0:
return 0
return addingElement(arr[1:]) + int(arr[0])
print(addingElement(nlist))
Output - 7402

Find the numbers in string and Sum them using list comprehension [sum only 1-9] [duplicate]

if i just read my sum_digits function here, it makes sense in my head but it seems to be producing wrong results. Any tip?
def is_a_digit(s):
''' (str) -> bool
Precondition: len(s) == 1
Return True iff s is a string containing a single digit character (between
'0' and '9' inclusive).
>>> is_a_digit('7')
True
>>> is_a_digit('b')
False
'''
return '0' <= s and s <= '9'
def sum_digits(digit):
b = 0
for a in digit:
if is_a_digit(a) == True:
b = int(a)
b += 1
return b
For the function sum_digits, if i input sum_digits('hihello153john'), it should produce 9
Notice that you can easily solve this problem using built-in functions. This is a more idiomatic and efficient solution:
def sum_digits(digit):
return sum(int(x) for x in digit if x.isdigit())
print(sum_digits('hihello153john'))
=> 9
In particular, be aware that the is_a_digit() method already exists for string types, it's called isdigit().
And the whole loop in the sum_digits() function can be expressed more concisely using a generator expression as a parameter for the sum() built-in function, as shown above.
You're resetting the value of b on each iteration, if a is a digit.
Perhaps you want:
b += int(a)
Instead of:
b = int(a)
b += 1
Another way of using built in functions, is using the reduce function:
>>> numeric = lambda x: int(x) if x.isdigit() else 0
>>> reduce(lambda x, y: x + numeric(y), 'hihello153john', 0)
9
One liner
sum_digits = lambda x: sum(int(y) for y in x if y.isdigit())
I would like to propose a different solution using regx that covers two scenarios:
1.
Input = 'abcd45def05'
Output = 45 + 05 = 50
import re
print(sum(int(x) for x in re.findall(r'[0-9]+', my_str)))
Notice the '+' for one or more occurrences
2.
Input = 'abcd45def05'
Output = 4 + 5 + 0 + 5 = 14
import re
print(sum(int(x) for x in re.findall(r'[0-9]', my_str)))
Another way of doing it:
def digit_sum(n):
new_n = str(n)
sum = 0
for i in new_n:
sum += int(i)
return sum
An equivalent for your code, using list comprehensions:
def sum_digits(your_string):
return sum(int(x) for x in your_string if '0' <= x <= '9')
It will run faster then a "for" version, and saves a lot of code.
Just a variation to #oscar's answer, if we need the sum to be single digit,
def sum_digits(digit):
s = sum(int(x) for x in str(digit) if x.isdigit())
if len(str(s)) > 1:
return sum_digits(s)
else:
return s
#if string =he15ll15oo10
#sum of number =15+15+10=40
def sum_of_all_Number(s):
num = 0
sum = 0
for i in s:
if i.isdigit():
num = num * 10 + int(i)
else:
sum = sum + num
num = 0
return sum+num
#if string =he15ll15oo10
#sum of digit=1+5+1+5+1+0=13
def sum_of_Digit(s):
sum = 0
for i in s:
if i.isdigit():
sum= sum + int(i)
return sum
s = input("Enter any String ")
print("Sum of Number =", sum_of_all_Number(s))
print("Sum Of Digit =", sum_of_Digit(s))
simply turn the input to integer by int(a) ---> using a.isdigit to make sure the input not None ('') ,
if the input none make it 0 and return sum of the inputs in a string simply
def sum_str(a, b):
a = int(a) if a.isdigit() else 0
b = int(b) if b.isdigit() else 0
return f'{a+b}'

How do I get my Median Program to work (part 2) [duplicate]

This question already has answers here:
What is the difference between '/' and '//' when used for division?
(16 answers)
Closed 7 years ago.
I am trying to make a median program. This is my code.
def median(list=[]):
x = 0
list = sorted(list)
if len(list) % 2 == 0:
b = int((len(list)/2))
print b
c = int(len(list)/2)
x = [list[b-1],list[c]]
print x
x = float((x[0]+x[1])/2)
print str(x)
else:
print list[((len(list)//2))]
When I run it, I get this
>>> median([1,2,3,4])
2
[2, 3]
2.0
What is happening?
Please note: I do not want any advice on ways to do it better, I just want help.
Try this, look for 2.0 instead of 2 on division
def median(list=[]):
x = 0
list = sorted(list)
if len(list) % 2 == 0:
b = int((len(list)/2.0))
print b
c = int(len(list)/2.0)
x = [list[b-1],list[c]]
print x
x = float((x[0]+x[1])/2.0)
print str(x)
else:
print list[((len(list)//2))]
Python 3.4 has statistics.median
Here is a example of how to use it
import statistics
values = [1, 2, 3, 6, 8]
print(statistics.median(values))
If you don't use python version 3.4 you could always right a function like this one i have included
def median(lst):
lst = sorted(lst)
if len(lst) < 1:
return None
if len(lst) %2 == 1:
return lst[((len(lst)+1)/2)-1]
else:
return float(sum(lst[(len(lst)/2)-1:(len(lst)/2)+1]))/2.0
while these may be the more pythonic way to do it, if you would like your specific function, you can do it like this
def median(list=[]):
x = 0
list = sorted(list)
if len(list) % 2 == 0:
b = int((len(list)/2.0))
print b
c = int(len(list)/2.0)
x = [list[b-1],list[c]]
print x
x = float((x[0]+x[1])/2.0)
print str(x)
else:
print list[((len(list)//2.0))]
median([1,2,3,4])
You should cast the elements of x to a float before taking the average:
def median(list=[]):
x = 0
list = sorted(list)
if len(list) % 2 == 0:
b = int(len(list)/2)
print b
c = int(len(list)/2)
x = [list[b-1],list[c]]
print x
x = (float(x[0])+float(x[1]))/2
print str(x)
else:
print list[((len(list)//2))]
median([1,2,3,4])
In the original you had x = float((x[0]+x[1])/2). So that's adding 2 integers and dividing them. If this is python 2 the you run into the integer division problem (I don't believe this will happen in python 3 because / is float division by default). You fix this by explicitly telling python that your values are floats (as I did above), or you can from __future__ import division and just use the default float division from python 3.
Also, b and c are both set to the same value so you don't need to store them both separately. Just use either b or c when calculating your list x

Sum of digits in a string

if i just read my sum_digits function here, it makes sense in my head but it seems to be producing wrong results. Any tip?
def is_a_digit(s):
''' (str) -> bool
Precondition: len(s) == 1
Return True iff s is a string containing a single digit character (between
'0' and '9' inclusive).
>>> is_a_digit('7')
True
>>> is_a_digit('b')
False
'''
return '0' <= s and s <= '9'
def sum_digits(digit):
b = 0
for a in digit:
if is_a_digit(a) == True:
b = int(a)
b += 1
return b
For the function sum_digits, if i input sum_digits('hihello153john'), it should produce 9
Notice that you can easily solve this problem using built-in functions. This is a more idiomatic and efficient solution:
def sum_digits(digit):
return sum(int(x) for x in digit if x.isdigit())
print(sum_digits('hihello153john'))
=> 9
In particular, be aware that the is_a_digit() method already exists for string types, it's called isdigit().
And the whole loop in the sum_digits() function can be expressed more concisely using a generator expression as a parameter for the sum() built-in function, as shown above.
You're resetting the value of b on each iteration, if a is a digit.
Perhaps you want:
b += int(a)
Instead of:
b = int(a)
b += 1
Another way of using built in functions, is using the reduce function:
>>> numeric = lambda x: int(x) if x.isdigit() else 0
>>> reduce(lambda x, y: x + numeric(y), 'hihello153john', 0)
9
One liner
sum_digits = lambda x: sum(int(y) for y in x if y.isdigit())
I would like to propose a different solution using regx that covers two scenarios:
1.
Input = 'abcd45def05'
Output = 45 + 05 = 50
import re
print(sum(int(x) for x in re.findall(r'[0-9]+', my_str)))
Notice the '+' for one or more occurrences
2.
Input = 'abcd45def05'
Output = 4 + 5 + 0 + 5 = 14
import re
print(sum(int(x) for x in re.findall(r'[0-9]', my_str)))
Another way of doing it:
def digit_sum(n):
new_n = str(n)
sum = 0
for i in new_n:
sum += int(i)
return sum
An equivalent for your code, using list comprehensions:
def sum_digits(your_string):
return sum(int(x) for x in your_string if '0' <= x <= '9')
It will run faster then a "for" version, and saves a lot of code.
Just a variation to #oscar's answer, if we need the sum to be single digit,
def sum_digits(digit):
s = sum(int(x) for x in str(digit) if x.isdigit())
if len(str(s)) > 1:
return sum_digits(s)
else:
return s
#if string =he15ll15oo10
#sum of number =15+15+10=40
def sum_of_all_Number(s):
num = 0
sum = 0
for i in s:
if i.isdigit():
num = num * 10 + int(i)
else:
sum = sum + num
num = 0
return sum+num
#if string =he15ll15oo10
#sum of digit=1+5+1+5+1+0=13
def sum_of_Digit(s):
sum = 0
for i in s:
if i.isdigit():
sum= sum + int(i)
return sum
s = input("Enter any String ")
print("Sum of Number =", sum_of_all_Number(s))
print("Sum Of Digit =", sum_of_Digit(s))
simply turn the input to integer by int(a) ---> using a.isdigit to make sure the input not None ('') ,
if the input none make it 0 and return sum of the inputs in a string simply
def sum_str(a, b):
a = int(a) if a.isdigit() else 0
b = int(b) if b.isdigit() else 0
return f'{a+b}'

swapping every two chars in the string with Python [duplicate]

I want to swap each pair of characters in a string. '2143' becomes '1234', 'badcfe' becomes 'abcdef'.
How can I do this in Python?
oneliner:
>>> s = 'badcfe'
>>> ''.join([ s[x:x+2][::-1] for x in range(0, len(s), 2) ])
'abcdef'
s[x:x+2] returns string slice from x to x+2; it is safe for odd len(s).
[::-1] reverses the string in Python
range(0, len(s), 2) returns 0, 2, 4, 6 ... while x < len(s)
The usual way to swap two items in Python is:
a, b = b, a
So it would seem to me that you would just do the same with an extended slice. However, it is slightly complicated because strings aren't mutable; so you have to convert to a list and then back to a string.
Therefore, I would do the following:
>>> s = 'badcfe'
>>> t = list(s)
>>> t[::2], t[1::2] = t[1::2], t[::2]
>>> ''.join(t)
'abcdef'
Here's one way...
>>> s = '2134'
>>> def swap(c, i, j):
... c = list(c)
... c[i], c[j] = c[j], c[i]
... return ''.join(c)
...
>>> swap(s, 0, 1)
'1234'
>>>
''.join(s[i+1]+s[i] for i in range(0, len(s), 2)) # 10.6 usec per loop
or
''.join(x+y for x, y in zip(s[1::2], s[::2])) # 10.3 usec per loop
or if the string can have an odd length:
''.join(x+y for x, y in itertools.izip_longest(s[1::2], s[::2], fillvalue=''))
Note that this won't work with old versions of Python (if I'm not mistaking older than 2.5).
The benchmark was run on python-2.7-8.fc14.1.x86_64 and a Core 2 Duo 6400 CPU with s='0123456789'*4.
If performance or elegance is not an issue, and you just want clarity and have the job done then simply use this:
def swap(text, ch1, ch2):
text = text.replace(ch2, '!',)
text = text.replace(ch1, ch2)
text = text.replace('!', ch1)
return text
This allows you to swap or simply replace chars or substring.
For example, to swap 'ab' <-> 'de' in a text:
_str = "abcdefabcdefabcdef"
print swap(_str, 'ab','de') #decabfdecabfdecabf
Loop over length of string by twos and swap:
def oddswap(st):
s = list(st)
for c in range(0,len(s),2):
t=s[c]
s[c]=s[c+1]
s[c+1]=t
return "".join(s)
giving:
>>> s
'foobar'
>>> oddswap(s)
'ofbora'
and fails on odd-length strings with an IndexError exception.
There is no need to make a list. The following works for even-length strings:
r = ''
for in in range(0, len(s), 2) :
r += s[i + 1] + s[i]
s = r
A more general answer... you can do any single pairwise swap with tuples or strings using this approach:
# item can be a string or tuple and swap can be a list or tuple of two
# indices to swap
def swap_items_by_copy(item, swap):
s0 = min(swap)
s1 = max(swap)
if isinstance(item,str):
return item[:s0]+item[s1]+item[s0+1:s1]+item[s0]+item[s1+1:]
elif isinstance(item,tuple):
return item[:s0]+(item[s1],)+item[s0+1:s1]+(item[s0],)+item[s1+1:]
else:
raise ValueError("Type not supported")
Then you can invoke it like this:
>>> swap_items_by_copy((1,2,3,4,5,6),(1,2))
(1, 3, 2, 4, 5, 6)
>>> swap_items_by_copy("hello",(1,2))
'hlelo'
>>>
Thankfully python gives empty strings or tuples for the cases where the indices refer to non existent slices.
To swap characters in a string a of position l and r
def swap(a, l, r):
a = a[0:l] + a[r] + a[l+1:r] + a[l] + a[r+1:]
return a
Example:
swap("aaabcccdeee", 3, 7) returns "aaadcccbeee"
Do you want the digits sorted? Or are you swapping odd/even indexed digits? Your example is totally unclear.
Sort:
s = '2143'
p=list(s)
p.sort()
s = "".join(p)
s is now '1234'. The trick is here that list(string) breaks it into characters.
Like so:
>>> s = "2143658709"
>>> ''.join([s[i+1] + s[i] for i in range(0, len(s), 2)])
'1234567890'
>>> s = "badcfe"
>>> ''.join([s[i+1] + s[i] for i in range(0, len(s), 2)])
'abcdef'
re.sub(r'(.)(.)',r"\2\1",'abcdef1234')
However re is a bit slow.
def swap(s):
i=iter(s)
while True:
a,b=next(i),next(i)
yield b
yield a
''.join(swap("abcdef1234"))
One more way:
>>> s='123456'
>>> ''.join([''.join(el) for el in zip(s[1::2], s[0::2])])
'214365'
>>> import ctypes
>>> s = 'abcdef'
>>> mutable = ctypes.create_string_buffer(s)
>>> for i in range(0,len(s),2):
>>> mutable[i], mutable[i+1] = mutable[i+1], mutable[i]
>>> s = mutable.value
>>> print s
badcfe
def revstr(a):
b=''
if len(a)%2==0:
for i in range(0,len(a),2):
b += a[i + 1] + a[i]
a=b
else:
c=a[-1]
for i in range(0,len(a)-1,2):
b += a[i + 1] + a[i]
b=b+a[-1]
a=b
return b
a=raw_input('enter a string')
n=revstr(a)
print n
A bit late to the party, but there is actually a pretty simple way to do this:
The index sequence you are looking for can be expressed as the sum of two sequences:
0 1 2 3 ...
+1 -1 +1 -1 ...
Both are easy to express. The first one is just range(N). A sequence that toggles for each i in that range is i % 2. You can adjust the toggle by scaling and offsetting it:
i % 2 -> 0 1 0 1 ...
1 - i % 2 -> 1 0 1 0 ...
2 * (1 - i % 2) -> 2 0 2 0 ...
2 * (1 - i % 2) - 1 -> +1 -1 +1 -1 ...
The entire expression simplifies to i + 1 - 2 * (i % 2), which you can use to join the string almost directly:
result = ''.join(string[i + 1 - 2 * (i % 2)] for i in range(len(string)))
This will work only for an even-length string, so you can check for overruns using min:
N = len(string)
result = ''.join(string[min(i + 1 - 2 * (i % 2), N - 1)] for i in range(N))
Basically a one-liner, doesn't require any iterators beyond a range over the indices, and some very simple integer math.
While the above solutions do work, there is a very simple solution shall we say in "layman's" terms. Someone still learning python and string's can use the other answers but they don't really understand how they work or what each part of the code is doing without a full explanation by the poster as opposed to "this works". The following executes the swapping of every second character in a string and is easy for beginners to understand how it works.
It is simply iterating through the string (any length) by two's (starting from 0 and finding every second character) and then creating a new string (swapped_pair) by adding the current index + 1 (second character) and then the actual index (first character), e.g., index 1 is put at index 0 and then index 0 is put at index 1 and this repeats through iteration of string.
Also added code to ensure string is of even length as it only works for even length.
DrSanjay Bhakkad post above is also a good one that works for even or odd strings and is basically doing the same function as below.
string = "abcdefghijklmnopqrstuvwxyz123"
# use this prior to below iteration if string needs to be even but is possibly odd
if len(string) % 2 != 0:
string = string[:-1]
# iteration to swap every second character in string
swapped_pair = ""
for i in range(0, len(string), 2):
swapped_pair += (string[i + 1] + string[i])
# use this after above iteration for any even or odd length of strings
if len(swapped_pair) % 2 != 0:
swapped_adj += swapped_pair[-1]
print(swapped_pair)
badcfehgjilknmporqtsvuxwzy21 # output if the "needs to be even" code used
badcfehgjilknmporqtsvuxwzy213 # output if the "even or odd" code used
One of the easiest way to swap first two characters from a String is
inputString = '2134'
extractChar = inputString[0:2]
swapExtractedChar = extractChar[::-1] """Reverse the order of string"""
swapFirstTwoChar = swapExtractedChar + inputString[2:]
# swapFirstTwoChar = inputString[0:2][::-1] + inputString[2:] """For one line code"""
print(swapFirstTwoChar)
#Works on even/odd size strings
str = '2143657'
newStr = ''
for i in range(len(str)//2):
newStr += str[i*2+1] + str[i*2]
if len(str)%2 != 0:
newStr += str[-1]
print(newStr)
#Think about how index works with string in Python,
>>> a = "123456"
>>> a[::-1]
'654321'

Categories