how do I do this with sliced notation?
ex. "Hello" to "HHeelloo"
You can iterate through the input string, then use the multiplication operator to duplicate the string and then concatenate again using join():
"".join(2 * s for s in "Hello")
You could simply loop each letter in your string and add it twice to a new string. For example
word = "Hello"
doubledWord = ""
for letter in word:
doubledWord += letter * 2
print(doubledWord)
Output
HHeelllloo
The term slicing in programming usually refers to obtaining a substring, sub-tuple, or sublist from a string, tuple, or list respectively. You cannot slice a string to double every character. Though you can use sliced notation- method 6. Here are some methods to get the desirable output.
Method 1:
input = Hello
output=""
for i in input:
output = output + i*2
print(output)
Method 2:
"".join(2 * i for i in "Hello")
Method 3:
s='Hello'
from itertools import chain,izip
''.join(chain(*izip(s,s)))
Method 4:
s.translate({ord(x):2*x for x in set(s)})
Method 5:
s = "Hello"
import re
re.sub('(.)', r'\1' * 2, s)
Method 6 (using sliced notation):
s = "Hello"
s1 = 2 * s
s2 = ""
for i in range(len(s)):
s2 += s1[i::len(s)]
print(s2)
All would result in:
HHeelllloo
You can use join function and for loop to an empty string. The letters will be double of all letters.
s="Hello"
"".join([x*2 for x in s])
Word = 'Hello'
number_of_time = 2
''.join([char*number_of_time for char in Word])
Output:
'HHeelllloo'
you can achieve it by iterating the whole string and at each iteration multiply the string by 2
str1 = 'Hello'
str2= ''
for i in range(len(str1)):
str2 += str1[i]*2
print(str2)
Using sliced notation in a non-trivial manner:
s = "Sajad"
s2 = 2 * "Sajad"
ss = ""
for i in range(len(s)):
ss += s2[i::len(s)]
print(ss)
Related
Given two strings suppose stringA and stringB (len(stringA)>len(stringB)), how do i remove all characters from stringA which are present in stringB? Assume that all characters in stringB are present in stringA
Here is what i tried:
a=input()
b=input()
for i in range(len(b)):
if b[i] not in a:
a.remove(b[i])
I expected it to remove characters from A, but resulting in an error, I am a beginner in python and i havent a clue which other method or approach i should use here
Use a set of B for efficiency and loop over all characters of A with a list comprehension to filter and join them:
s = set(B)
out = ''.join([c for c in A if not c in s])
stringA = input()
stringB = input()
for char in stringB:
stringA = stringA.replace(char, "")
print(stringA)
s1 = input()
s2 = input()
new_s1 = ""
new_s2 = ""
for char in s1:
if char not in s2:
new_s1 += char
for char in s2:
if char not in s1:
new_s2 += char
print(new_s1)
print(new_s2)
str object has no method called remove. You have to use sth like replace or use set for efficiency:
out = "".join(set(a).difference(set(b)))
Note that this will not necessarily maintain order of the characters of A.
I am trying to extract numbers from a string. Without any fancy inports like regex and for or if statements.
Example
495 * 89
Output
495 89
Edit I have tried this:
num1 = int(''.join(filter(str.isdigit, num)))
It works, but doesn't space out the numbers
Actually, regex is a very simple and viable option here:
inp = "495 * 89"
nums = re.findall(r'\d+(?:\.\d+)?', inp)
print(nums) # ['495', '89']
Assuming you always expect integers and you want to avoid regex, you could use a string split approach with a list comprehension:
inp = "495 * 89"
parts = inp.split()
nums = [x for x in parts if x.isdigit()]
print(nums) # ['495', '89']
You can do this without much fancy stuff
s = "495 * 89"
#replace non-digits with spaces, goes into a list of characters
li = [c if c.isdigit() else " " for c in s ]
#join characters back into a string
s_digit_spaces = "".join(li)
#split will separate on space boundaries, multiple spaces count as one
nums = s_digit_spaces.split()
print(nums)
#one-liner:
print ("".join([c if c.isdigit() else " " for c in s ]).split())
output:
['495', '89']
['495', '89']
#and with non-digit number stuff
s = "495.1 * -89"
print ("".join([c if (c.isdigit() or c in ('-',".")) else " " for c in s ]).split())
output:
['495.1', '-89']
Finally, this works too:
print ("".join([c if c in "0123456789+-." else " " for c in s ]).split())
You're close.
You don't want to int() a single value when there are multiple numbers in the string. The filter function is being applied over characters, since strings are iterable that way
Instead, you need to first split the string into its individual tokens, then filter whole numerical strings, then cast each element
s = "123 * 54"
digits = list(map(int, filter(str.isdigit, s.split())))
Keep in mind, this only handles non-negative integers
How can I count the number of characters at the start/end of a string in Python?
For example, if the string is
'ffffhuffh'
How would I count the number of fs at the start of the string? The above string with a f should output 4.
str.count is not useful to me as a character could be in the middle of the string.
A short and simple way will be to use the str.lstrip method, and count the difference of length.
s = 'ffffhuffh'
print(len(s)-len(s.lstrip('f')))
# output: 4
str.lstrip([chars]):
Return a copy of the string with leading characters removed. The chars
argument is a string specifying the set of characters to be removed.
Try this, using itertools.takewhile():
import itertools as it
s = 'ffffhuffh'
sum(1 for _ in it.takewhile(lambda c: c == 'f', s))
=> 4
Similarly, for counting the characters at the end:
s = 'huffhffff'
sum(1 for _ in it.takewhile(lambda c: c == 'f', reversed(s)))
=> 4
You may use regular expression with re.match to find the occurrence of any character at the start of the string as:
>>> import re
>>> my_str = 'ffffhuffh'
>>> my_char = 'f'
>>> len(re.match('{}*'.format(my_char), my_str).group())
4
Building on Oscar Lopez's answer, I want to handle the case you mention of the end of the string: use reversed()
import itertools as it
my_string = 'ffffhuffh'
len(list(it.takewhile(lambda c: c == my_string[-1], reversed(my_string))))
=> 1
You can create a function and iterate through your string and return the count of the desired char in the input string's beginning or end like this example:
# start = True: Count the chars in the beginning of the string
# start = False: Count the chars in the end of the string
def count_char(string= '', char='', start=True):
count = 0
if not start:
string = string[::-1]
for k in string:
if k is char:
count += 1
else:
break
return count
a = 'ffffhuffh'
print(count_char(a, 'f'))
b = a[::-1]
print(count_char(b, 'f', start=False))
Output:
4
4
You may also use itertools.groupby to find the count of the occurrence of the first element at the start of the string as:
from itertools import groupby
def get_first_char_count(my_str):
return len([list(j) for _, j in groupby(my_str)][0])
Sample run:
>>> get_first_char_count('ffffhuffh')
4
>>> get_first_char_count('aywsnsb')
1
re.sub select first letter with repeat( (^(\w)\2*) ), len count frequency.
len(re.sub(r'((^\w)\2*).*',r'\1',my_string))
So, for input:
accessibility,random good bye
I want output:
a11y,r4m g2d bye
So, basically, I have to abbreviate all words of length greater than or equal to 4 in the following format: first_letter + length_of_all_letters_in_between + last_letter
I try to do this:
re.sub(r"([A-Za-z])([A-Za-z]{2,})([A-Za-z])", r"\1" + str(len(r"\2")) + r"\3", s)
But it does not work. In JS, I would easily do:
str.replace(/([A-Za-z])([A-Za-z]{2,})([A-Za-z])/g, function(m, $1, $2, $3){
return $1 + $2.length + $3;
});
How do I do the same in Python?
EDIT: I cannot afford to lose any punctuation present in original string.
What you are doing in JavaScript is certainly right, you are passing an anonymous function. What you do in Python is to pass a constant expression ("\12\3", since len(r"\2") is evaluated before the function call), it is not a function that can be evaluated for each match!
While anonymous functions in Python aren't quite as useful as they are in JS, they do the job here:
>>> import re
>>> re.sub(r"([A-Za-z])([A-Za-z]{2,})([A-Za-z])", lambda m: "{}{}{}".format(m.group(1), len(m.group(2)), m.group(3)), "accessability, random good bye")
'a11y, r4m g2d bye'
What happens here is that the lambda is called for each substitution, taking a match object. I then retrieve the needed information and build a substitution string from that.
The issue you're running into is that len(r'\2') is always 2, not the length of the second capturing group in your regular expression. You can use a lambda expression to create a function that works just like the code you would use in JavaScript:
re.sub(r"([A-Za-z])([A-Za-z]{2,})([A-Za-z])",
lambda m: m.group(1) + str(len(m.group(2)) + m.group(3),
s)
The m argument to the lambda is a match object, and the calls to its group method are equivalent to the backreferences you were using before.
It might be easier to just use a simple word matching pattern with no capturing groups (group() can still be called with no argument to get the whole matched text):
re.sub(r'\w{4,}', lambda m: m.group()[0] + str(len(m.group())-2) + m.group()[-1], s)
tmp, out = "",""
for ch in s:
if ch.isspace() or ch in {",", "."}:
out += "{}{}{}{}".format(tmp[0], len(tmp) - 2, tmp[-1], ch) if len(tmp) > 3 else tmp + ch
tmp = ""
else:
tmp += ch
out += "{}{}{}".format(tmp[0], len(tmp) - 2, tmp[-1]) if len(tmp) > 3 else tmp
print(out)
a11y,r4m g2d bye
If you only want alpha characters use str.isalpha:
tmp, out = "", ""
for ch in s:
if not ch.isalpha():
out += "{}{}{}{}".format(tmp[0], len(tmp) - 2, tmp[-1], ch) if len(tmp) > 3 else tmp + ch
tmp = ""
else:
tmp += ch
out += "{}{}{}".format(tmp[0], len(tmp) - 2, tmp[-1]) if len(tmp) > 3 else tmp
print(out)
a11y,r4m g2d bye
The logic is the same for both, it is just what we check for that differs, if not ch.isalpha() is False we found a non alpha character so we need to process the tmp string and add it to out output string. if len(tmp) is not greater than 3 as per the requirement we just add the tmp string plus the current char to our out string.
We need a final out += "{}{}{} outside the loop to catch when a string does not end in a comma, space etc.. If the string did end in a non-alpha we would be adding an empty string so it would make no difference to the output.
It will preserve punctuation and spaces:
s = "accessibility,random good bye !! foobar?"
def func(s):
tmp, out = "", ""
for ch in s:
if not ch.isalpha():
out += "{}{}{}{}".format(tmp[0], len(tmp) - 2, tmp[-1], ch) if len(tmp) > 3 else tmp + ch
tmp = ""
else:
tmp += ch
return "{}{}{}".format(tmp[0], len(tmp) - 2, tmp[-1]) if len(tmp) > 3 else tmp
print(func(s,3))
a11y,r4m g2d bye !! f4r?
Keep it simple...
>>> s = "accessibility,random good bye"
>>> re.sub(r'\B[A-Za-z]{2,}\B', lambda x: str(len(x.group())), s)
'a11y,r4m g2d bye'
\B which matches between two word characters or two non-word chars helps to match all the chars except first and last.
As an alternative precise way you can use a separate function for re.sub and use the simple regex r"(\b[a-zA-Z]+\b)".
>>> def replacer(x):
... g=x.group(0)
... if len(g)>3:
... return '{}{}{}'.format(g[0],len(g)-2,g[-1])
... else :
... return g
...
>>> re.sub(r"(\b[a-zA-Z]+\b)", replacer, s)
'a11y,r4m g2d bye'
Also as a pythonic and general way, to get the replaced words within a list you can use a list comprehension using re.finditer :
>>> from operator import sub
>>> rep=['{}{}{}'.format(i.group(0)[0],abs(sub(*i.span()))-2,i.group(0)[-1]) if len(i.group(0))>3 else i.group(0) for i in re.finditer(r'(\w+)',s)]
>>> rep
['a11y', 'r4m', 'g2d', 'bye']
The re.finditer will returns a generator contains all matchobjects then you can iterate over it and get the start and end of matchobjects with span() method.
Using regex and comprehension:
import re
s = "accessibility,random good bye"
print "".join(w[0]+str(len(w)-2)+w[-1] if len(w) > 3 else w for w in re.split("(\W)", s))
Gives:
a11y,r4m g2d bye
Have a look at the following code
sentence = "accessibility,random good bye"
sentence = sentence.replace(',', " ")
sentence_list = sentence.split(" ")
for item in sentence_list:
if len(item) >= 4:
print item[0]+str(len(item[1:len(item)-1]))+item[len(item)-1]
The only thing you should take care of comma and other punctuation characters.
what i want to do is take a string and for each character make the ordinal value 1 more from the value it has.
myinput=input("Message : ")
mylist =list(myinput) #convert to list in order to take each character
for character in mylist:
mylist[character]+=ord(mylist[character])+1
print(character)
The problem is with the "ord(mylist[character])+1"
Thank you!
Probably you are looking for the next:
>>> m = raw_input('Message:')
Message:asdf
>>> ''.join(chr(ord(c) + 1) for c in m)
'bteg'
Notes:
use raw_input when you need to get string input from a user;
ord convert character to integer, chr - vise versa;
... for c in m syntax is a generator expression. It is also used for list comprehension.
Three problems here. First, you're mixing up list indices and list elements. Second, you didn't convert back to a character (I'm assuming you want characters, not numbers). Third, you're adding to the existing value.
One way:
for i range(len(mylist)):
mylist[i] = chr(ord(mylist[i])+1)
Another way:
for i, character in enumerate(mylist):
mylist[i] = chr(ord(character)+1)
Instead of
for character in mylist:
mylist[character]+=ord(mylist[character])+1
(where character is a list index and therefore invalid), you probably want:
mylist = [ord(character) + 1 for character in mylist]
Or a Counter.
You can do like this
def ordsum(astring, tablesize):
sum = 0
for num in range(len(astring)):
sum = sum + ord(astring[num])
return sum
myinput = input() # use raw_input() in Python 2
myinput = map(lambda ch: chr(ord(ch) + 1), myinput)
# or list comp.
myinput = [chr(ord(ch) + 1) for ch in myinput]
You can iterate directly over a string, you do not have to make it a list first. If your end goal is to have a new string, you can do this:
myinput=input("Message : ")
result = []
for character in myinput:
result.append( chr( ord( character ) + 1 )
mynewstring = ' '.join(result)