How does str.replace() method work? - python

I have this input:
'0472/91.39.17'
I want to replace my input with '1234567890' one by one like this:
'1234/56.78.90'
But my outcome is
0472/91.09.17
Here's my code
phone = '0472/91.39.17'
repl = 1234567890
for i in phone:
if i.isdigit():
for j in str(repl):
x = phone.replace(i, j)
print(x)
What is the proper way to do this?

You can turn repl into an iterator and use a generator expression to replace any value in phone with the next value in the repl iter if the original value is a digit. Re-combine that together with ''.join to get a string as a result, and Bob's your uncle.
repliter = iter(str(repl))
result = ''.join(next(repliter) if c.isdigit() else c for c in phone)
# the ternary expression here evaluates to:
# if c.isdigit():
# next(repliter)
# else:
# c
Note that this will crash with a StopIteration error if your phone number contains more than 10 digits, so consider using itertools.cycle for repliter instead.
import itertools
repliter = itertools.cycle(str(repl)) # 1 2 3 4 5 6 7 8 9 0 1 2 3 ...

I was thinking you could use itertools count with modulus for numbers higher than 10.
from itertools import count
c = count(0) # start number
phone = '0472/91.39.17'
''.join(str(next(c) % 10) if item.isdigit() else item for item in phone)

Related

Count the amount of numbers that are length of 5 and has exactly two repeating numbers

I'm trying to count the amount of numbers that are length of 5 and has exactly two repeating numbers (where zero can be leading like 00123). What I did:
def checkNumber(num):
temp = [0] * 10
for d in map(int, str(num)):
temp[d] += 1
contains_two_unique_digits = False
for d in temp:
if d > 2:
return False
if d == 2:
if contains_two_unique_digits:
return False
contains_two_unique_digits = True
return True
counter = 0
for num in range(10000,100000):
counter += checkNumber(num)
print(counter)
But of course it does not count the cases with a leading zeros. How can I add them here? Python does not allow 001234 numbers.
The zfill method of the str type might be of help.
>>> "123".zfill(5)
'00123'
>>> "123456789".zfill(5)
'123456789'
To convert an int to a str, simply use str:
>>> str(123)
'123'
If you NEED to accept integers in python, then you are correct that no solution can be made. If you can accept a string and treat the values inside as integers, then you can definitely make it happen. A integer or float with leading zeros will always cause an error in Python.
def checkNumber(string_input):
# is it a string?
if not isinstance(string_input, str):
string_input = str(string_input)
# does it have five characters?
if not len(string_input) == 5:
raise ValueError('You must enter a string of length 5.')
counter_list = [0] * 10
# iterate over the string and count how many of each integer we have
for value in string_input:
if value.isdigit():
counter_list[int(value)] += 1
# check to see if any of them have identically two
for value_count in counter_list:
if value_count == 2:
return True
return False
print(checkNumber('01234'))
If you want to iterate over numbers by their digit representation, then itertool.product() will likely be more useful. itertools.product(string.digits, repeat=5) will yield each of the numbers you need, as digit tuples.
Taking advantage of collections.Counter can also help here, and avoids the flag / loop logic.
from collections import Counter
from itertools import product
from typing import Tuple
import string
def has_two_repeats(digits: Tuple[str, ...]):
counts = Counter(digits).values()
return (
# no digits occur more than 2 times
sum(count > 2 for count in counts) == 0 and
# one digit occcurs two times
sum(count == 2 for count in counts) == 1
)
def all_two_repeats_five_digits() -> int:
return sum(
has_two_repeats(digits)
for digits in product(string.digits, repeat=5)
)
print(all_two_repeats_five_digits())

scope of a variable in python for this question

I don't know why, but I am getting value of scope as final as 0 even len(s) as zero in the last line of countfrequency(s) function.
import collections
def countfrequency(s):
final = 0
flag = 1
d = dict(collections.Counter(s))
for item in d:
if d[item] <= k:
flag = 0
if flag == 1: #Here
final = max(final, len(s))
print(final)
s = "ababbc"
k = 2
for x in range(len(s)):
for y in range(1, len(s)):
countfrequency(s[x:y + 1])
It is because of 2 reasons :
Value of flag is 0 at last so it wont change the value of final
Length function takes object as a parameter and when unchanged it gives 0
So you can can either make flag 1 so that control goes inside if condition or print the value of len(s) out side the if condition
In addition to the answer posted by shaktiraj jadeja, the modified code is as follows:
import collections
def countfrequency(s, k):
final = 0
flag = 0
d = dict(collections.Counter(s))
# print(d)
for item in d:
if d[item] > k:
flag = 1
break
if flag == 1: #Here
# print("Inside:", final, len(s))
final = max(final, len(s))
print(final)
s = "ababbc"
k = 2
for x in range(len(s)):
for y in range(1, len(s)):
# print(s[x:y])
countfrequency(s[x:y + 1], k)
To start with there is no problem of scope.
Now lets get back to the problem
Lets define a rule.
Rule: If a sub string has each character repeated more than k(=2) times in it. Then it is a good substring. Else it is a bad substring
Then your code simply prints the length of good sub string or 0 in case of bad substring
In short in your example string s= "ababbc" contains no good substring
if you try S = "aaaaaa" you will see many numbers printed other than 0 (exactly 11 0's and 10 other numbers)
Now either this was your confusion or you wrote the wrong code for some logic
I hope this helps

Formatting unknown output in a table in Python

Help! I'm a Python beginner given the assignment of displaying the Collatz Sequence from a user-inputted integer, and displaying the contents in columns and rows. As you may know, the results could be 10 numbers, 30, or 100. I'm supposed to use '\t'. I've tried many variations, but at best, only get a single column. e.g.
def sequence(number):
if number % 2 == 0:
return number // 2
else:
result = number * 3 + 1
return result
n = int(input('Enter any positive integer to see Collatz Sequence:\n'))
while sequence != 1:
n = sequence(int(n))
print('%s\t' % n)
if n == 1:
print('\nThank you! The number 1 is the end of the Collatz Sequence')
break
Which yields a single vertical column, rather than the results being displayed horizontally. Ideally, I'd like to display 10 results left to right, and then go to another line. Thanks for any ideas!
Something like this maybe:
def get_collatz(n):
return [n // 2, n * 3 + 1][n % 2]
while True:
user_input = input("Enter a positive integer: ")
try:
n = int(user_input)
assert n > 1
except (ValueError, AssertionError):
continue
else:
break
sequence = [n]
while True:
last_item = sequence[-1]
if last_item == 1:
break
sequence.append(get_collatz(last_item))
print(*sequence, sep="\t")
Output:
Enter a positive integer: 12
12 6 3 10 5 16 8 4 2 1
>>>
EDIT Trying to keep it similar to your code:
I would change your sequence function to something like this:
def get_collatz(n):
if n % 2 == 0:
return n // 2
return n * 3 + 1
I called it get_collatz because I think that is more descriptive than sequence, it's still not a great name though - if you wanted to be super explicit maybe get_collatz_at_n or something.
Notice, I took the else branch out entirely, since it's not required. If n % 2 == 0, then we return from the function, so either you return in the body of the if or you return one line below - no else necessary.
For the rest, maybe:
last_number = int(input("Enter a positive integer: "))
while last_number != 1:
print(last_number, end="\t")
last_number = get_collatz(last_number)
In Python, print has an optional keyword parameter named end, which by default is \n. It signifies which character should be printed at the very end of a print-statement. By simply changing it to \t, you can print all elements of the sequence on one line, separated by tabs (since each number in the sequence invokes a separate print-statement).
With this approach, however, you'll have to make sure to print the trailing 1 after the while loop has ended, since the loop will terminate as soon as last_number becomes 1, which means the loop won't have a chance to print it.
Another way of printing the sequence (with separating tabs), would be to store the sequence in a list, and then use str.join to create a string out of the list, where each element is separated by some string or character. Of course this requires that all elements in the list are strings to begin with - in this case I'm using map to convert the integers to strings:
result = "\t".join(map(str, [12, 6, 3, 10, 5, 16, 8, 4, 2, 1]))
print(result)
Output:
12 6 3 10 5 16 8 4 2 1
>>>

How to access lists elements particular digits in python?

str1= ",".join(str(e) for e in paths)
str2= ",".join(str(e) for e in newlist)
print(str1)
print(str2)
for j in str2:
for i in str1:
if (j[0]==i[0]):
print('number is {}'.format(i))
Hey, I was making program where I needed to to access lists elements particular digits like if one list is [12,23,34] and another is [13,34],I want to access the first elements i.e 12's digits i.e 1 & 2 and compare it with another list and if any equal digit occurs i want to print the first element of the first list.
Like in our example 12 & 13 have 1 as equal digit I want to print 12.I am trying it from several days but getting stuck.And also I tried converting it in string then also some problem arised.
In the above example I am getting the particular digits printed like this:
number is 1
number is 3
number is 3
number is ,
number is ,
number is 1
number is 4
I dont want the 'comma' ,and if a match occurs the number should be printed as mentioned in the example.Any help would be highly appreciated.
Thanks.
Wouldn't keeping them as lists be easier to work with?
If you only want to compare the same indexes, then:
In []:
l1 = [12,23,34]
l2 = [13,34]
for a, b in zip(l1, l2):
if a//10 == b//10:
print(a)
Out[]:
12
Or you want to check any index:
In []:
import itertools as it
l1 = [12,23,34]
l2 = [13,34]
for a, b in it.product(l1, l2):
if a//10 == b//10:
print(a)
Out[]:
12
34
try this
str1= ",".join(str(e) for e in paths)
str2= ",".join(str(e) for e in newlist)
print(str1)
print(str2)
for j in str2:
for i in str1:
if (j[0]==i[0] and (i and j != ',')):
print('number is {}'.format(i))
output
12,23,34
13,34
number is 1
number is 3
number is 3
number is 3
number is 3
number is 4
This should work for your use-case
list1 = [123, 12, 32232, 1231]
list2 = [1232, 23243, 54545]
def find_intersection(list1, list2):
list2_digits = set.union(*[get_digits(x) for x in list2])
for num1 in list1:
digits1 = get_digits(num1)
for num2 in list2:
digits2 = get_digits(num2)
if digits1.intersection(digits2):
print 'Found Match', num1, num2 # We found a match
# Break here unless you want to find all possible matches
def get_digits(num):
d = set()
while num > 0:
d.add(num % 10)
num = num / 10
return d
find_intersection(list1, list2)
I'm not sure I totally understand the question, however:
list1 = [13,23,34]
list2 = [24,18,91]
list1 = list(map(str,list1)) #Map the arrays of ints to arrays of strings
list2 = list(map(str,list2))
for j in list1:
for i in list2:
for character in j:
if character in i:
print(j+' matches with '+i)
break
Prints out:
13 matches with 18
13 matches with 91
23 matches with 24
34 matches with 24

Python - replay values in list

Please help for task with the list in Python my logic is bad works:( .
This is full text of task: Write a program that takes a list of
numbers on one line and displays the values in a single row, are
repeated in it more than once.
To solve the problem can be useful sort method list.
The procedure for withdrawal of repetitive elements may be arbitrary.
My beginning code is :
st = (int(i) for i in input().split())
ls = []
for k in st:
if k == k + 1 and k > 1:
Task is : if we have replay value in list we must print it. We only can use sort() method and without any modules importing.
Results Examples:
Sample Input 1:
4 8 0 3 4 2 0 3
Sample Output 1:
0 3 4
Sample Input 2:
10
Sample Output 2:
Sample Input 3:
1 1 2 2 3 3
Sample Output 3:
1 2 3
This code isn't run( sort() function doesn't want sort my_list. But I must input values like my_list = (int(k) for k in input().split())
st = list(int(k) for k in input())
st.sort()
for i in range(0,len(st)-1):
if st[i] == st[i+1]:
print(str(st[i]), end=" ")
my_list = (int(k) for k in input().split())
After running this line, my_list is a generator, something that will create a sequence - but hasn't yet done so. You can't sort a generator. You either need to use []:
my_list = [int(k) for k in input().split()]
my_list.sort()
which makes my_list into a list from the start, instead of a generator, or:
my_list = list(int(k) for k in input().split()))
my_list.sort()
gather up the results from the generator using list() and then store it in my_list.
Edit: for single digits all together, e.g. 48304, try [int(k) for k in input()]. You can't usefully do this with split().
Edit: for printing the results too many times: make the top of the loop look backwards a number, like this, so if it gets to the second or third number of a repeating number, it skips over and continues on around the loop and doesn't print anything.
for i in range(0,len(st)-1):
if st[i] == st[i-1]:
continue
if st[i] == st[i+1]:
print...
st = (int(i) for i in input().split())
used = []
ls = []
for k in st:
if k in used: # If the number has shown up before:
if k not in used: ls.append(k) # Add the number to the repeats list if it isn't already there
else:
used.append(k) # Add the number to our used list
print ' '.join(ls)
In summary, this method uses two lists at once. One keeps track of numbers that have already shown up, and one keeps track of second-timers. At the end the program prints out the second-timers.
I'd probably make a set to keep track of what you've seen, and start appending to a list to keep track of the repeats.
lst = [num for num in input("prompt ").split()]
s = set()
repeats = []
for num in lst:
if num in s and num not in repeats:
repeats.append(num)
s.add(num)
print ' '.join(map(str,repeats))
Note that if you don't need to maintain order in your output, this is faster:
lst = [num for num in input("prompt ").split()]
s = set()
repeats = set()
for num in lst:
if num in s:
repeats.add(num)
s.add(num)
print ' '.join(map(str, repeats))
Although if you can use imports, there's a couple cool ways to do it.
# Canonically...
from collections import Counter
' '.join([num for num,count in Counter(input().split()).items() if count>1])
# or...
from itertools import groupby
' '.join([num for num,group in groupby(sorted(input().split())) if len(list(group))>1])
# or even...
from itertools import tee
lst = sorted(input('prompt ').split())
cur, nxt = tee(lst)
next(nxt) # consumes the first element, putting it one ahead.
' '.join({cur for (cur,nxt) in zip(cur,nxt) if cur==nxt})
this gives the answers you're looking for, not sure if it's exactly the intended algorithm:
st = (int(i) for i in input().split())
st = [i for i in st]
st.sort()
previous = None
for current in st:
if ((previous is None and current <= 1)
or (previous is not None and current == previous + 1)):
print(current, end=' ')
previous = current
>>> "4 8 0 3 4 2 0 3"
0 3 4
>>> "10"
>>> "1 1 2 2 3 3"
1 2 3
updated to:
start with st = (int(i) for i in input().split())
use only sort method, no other functions or methods... except print (Python3 syntax)
does that fit the rules?

Categories

Resources