Get n Characters from String specified in python [closed] - python

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
Let s = "%2ABCDE" - get first 2 characters from string
then output should be "AB".
Need to get characters from string specified by numeral in string.
E.g. s1="%12ABCDERTYUIOPLKHGF" - get first 12 characters from string.
I tried to get digit using re.findall('\d+', string ), but this creates problem if my string would be "%2ABCD1".
Please suggest

s = "%2ABCDE"
number = ""
offset = 0
for i in range(len(s)):
if s[i] == "%":
continue
elif s[i].isdigit():
number += s[i]
else:
offset = i
break
print(s[offset:int(number) + offset])
Output: AB

A simpler way of doing this would be to do the following:
txt = "%2ABCDE"
number_list = [s for s in txt if s.isdigit()]
number_concate = int("".join(number_list))
txt_filtered = txt[len(number_list)+1:]
print(txt_filtered[:number_concate])
Outputs AB for string "%2ABCDE"
Outputs ABCDERTYUIOP for string "%12ABCDERTYUIOPLKHGF"
You are taking your string, doing a list comprehension of the string if the digit exists, then joining the list and changing this to an integer to allow for you to filter your string accordingly. Then you strip the string to only the characters and you have your answer printed out.

import re
s = '%2ABCDERTYUIOPLKHGF'
numeral_instruction = re.search(r'%\d+',s).group(0)
start = len(numeral_instruction)
stop = start + int(numeral_instruction[1:])
s[start:stop]
outputs
AB

You can get the position of the first non-digit character in the string (skipping the %) and use that as the basis to get the length and form a substring:
s1="%12ABCDERTYUIOPLKHGF"
i = next(i for i,c in enumerate(s1[1:],1) if not c.isdigit())
result = s1[i:i+int(s1[1:i])]
print(result)
ABCDERTYUIOP
If the first number in the string is not always at index 1, you can skip a variable number of characters using the same technique:
s1="*:%12ABCDERTYUIOPLKHGF"
start = next(i for i,c in enumerate(s1) if c.isdigit())
end = next(i for i,c in enumerate(s1[start:],start) if not c.isdigit())
result = s1[end:end+int(s1[start:end])]
print(result)
ABCDERTYUIOP
If you want to use the re module, you only need the first occurrence of a number, so use re.search() instead of re.findall():
import re
m = re.search(r"\d+",s1)
result = s1[m.end():m.end()+int(m.group())]
print(result)
ABCDERTYUIOP

Related

How do I add numbers to the end of a string to get 8 characters python [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I know this is a very simple question for anyone who knows python, but I need to know how to take a name like JOHN and use a loop to keep adding "1" until it reaches 8 characters.
AKA JOHN1111
Edit: Thank you all so much for all the different ways to complete this. I am new to python and certainly new to this website.
You don't need a loop.
s = 'JOHN'
if len(s) < 8:
s = s + '1'*(8-len(s))
If you really like loops:
s = 'JOHN'
while len(s) < 8:
s += '1'
string has a method for that: str.ljust
>>> t="JOHN"
>>> t.ljust(8,"1")
'JOHN1111'
To do such a thing, simply create a while loop that adds a custom character to a string while the string is not of a certain length:
def pad_string(string, length, character = ' '):
while len(string) < length:
string += character
return string
Or, the more "pythonic" method for loop method:
def pad_string(string, length, character = ' '):
if len(string) > length:
return string
for character_number in range(length - len(string)):
string += character
return string
Usage:
pad_string('JOHN', 8, '1') # 'JOHN1111'
pad_string('JOHN', 2, '1') # 'JOHN'
Using len() you can get the length of the word.
subtract 8 from it.
If result is 0 that no need to do anything. If not add 1 to it and repeat it using (*) until 8 character.
name = 'JOHN'
if len(name) < 8 :
name = name + '1' * (8-len(name))
print(name)

string concatenation in a loop happens to be on the left . Why? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 2 years ago.
Improve this question
String concatenation happens to be on the right side, example:
foo = 'Sorting1234'
foo += 'er'
print(foo)
Sorting1234er
But in a loop this happens:
string = 'Sorting1234'
x = ''
for c in string:
if c.islower():
x+=c
if c.isupper():
x+=c
print(x)
Sorting
I would expect the output to be:
ortingS
Since I am 'appending' the lowercase first in the loop and 'appending' the uppercase later.
At the moment, you are processing the letters in the order of the original string, rather than by case. This means that your current for loop has little effect but to prevent the printing of numeric values.
One way to achieve the behaviour you're looking for, with the lower case characters appended first, would be to use two loops: the first looking for lower case characters and the second looking for upper case characters, i.e.:
string = 'Sorting1234'
x = ''
for c in string:
if c.islower():
x += c
for c in string:
if c.isupper():
x += c
print(x)
Output:
ortingS
An alternative way, requiring one pass over the string, could be to store lists of the lower and upper case characters, then join them at the end:
lower, upper = [], []
for c in string:
if c.islower():
lower.append(c)
elif c.isupper():
upper.append(c)
print(''.join(lower + upper))
Output:
ortingS
string = 'Sorting1234'
x = ''
for c in string:
if c.islower():
x+=c
if c.isupper():
x+=c
print(x)
print(x)
x=''
#x += c -> x = x + x -> appends c to the right of x, which it's doing it correctly
When printing the output you can see:
S
So
Sor
Sort
Sorti
Sortin
Sorting
You can see you are simply looping through the string and appending each letter, the if statements are practically useless in your case.

How to sort alphabetically without repetitious letters in python? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I am trying to sort an input string alphabetically but without repeat two letters beside each other. (abcabc, not aabbcc)
for example, if the input was "aaccbb" the output will be "abcabc"
right now I wrote this line of code. but it just gives me alphabetically sorting. how do I can prevent the repetition of two letters?
s = str(input())
s2 = sorted(s)
s3 = "".join(s2)
print(s3)
from collections import Counter
def layered_sort(s):
if not s: return s
c = Counter(s)
keys = sorted(c)
max_repeats = max(c.values())
return "".join([k for i in range(max_repeats) for k in keys if c[k] > i])
test_cases = (
"aaccbb",
"aacb",
"aaab",
"the rain in spain falls mainly on the plain"
)
for s in test_cases:
print(repr(s), "sorts to", repr(layered_sort(s)))
Result:
'aaccbb' sorts to 'abcabc'
'aacb' sorts to 'abca'
'aaab' sorts to 'abaa'
'the rain in spain falls mainly on the plain' sorts to ' aefhilmnoprsty aehilnpst ailn ailn ain n '
I wrote a recursive function to do that. I splits the string after the first set is sorted and keeps doing the same with the remaining string
def last_part_sort(in_str):
in_str = sorted(in_str)
new_str = []
exclude_ix = []
for i in range(1, len(in_str)):
if in_str[i] == in_str[i-1]:
new_str.append(in_str[i])
exclude_ix.append(i)
lead_string = ''.join([in_str[i] for i in range(len(sorted(in_str))) if i not in exclude_ix])
trail_string = ''.join([s for s in new_str])
if trail_string == '':
return lead_string
return lead_string + last_part_sort(trail_string)
For your example
last_part_sort(input_str)
out: 'abcabc'
For more duplications
input_str = 'aaaabbcc'
out: 'abcabcaa'
input_str = 'aaaabbbcc'
out: 'abcabcaba'
Use itertools count with defaultdict to create tuples with a cumulative counter on character observations. These tuples are then sorted naturally with sorted and we can pluck off the desired element when we join.
from collections import defaultdict
from itertools import count
def goofy_sort(s):
d = defaultdict(count)
l = [(next(d[x]), x) for x in s]
return "".join([y for _, y in sorted(l)])
Using #Kevin's test cases
test_cases = (
"aaccbb",
"aacb",
"aaab",
"the rain in spain falls mainly on the plain"
)
print(*map(goofy_sort, test_cases), sep="\n")
abcabc
abca
abaa
aefhilmnoprsty aehilnpst ailn ailn ain n
You can use a regular expression:
import re
r = re.compile(r"(.)\1{0,}")
r.findall("aaaaaaaabbbbbbccdeeee") # ['a', 'b', 'c', 'd', 'e']
The regexp works as follows:
. matches any character
(.) puts that character into a capture group
\1 takes the first capture group
{0,} expects zero or more repetitions of that group

Determine how many times a substring occurs adjacently in a string in Python [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I want to calculate how many times a substring occurs "adjacently" in a string,
for example, given the string "8448442844" and the substring "844", I want the result "2".
I know the string.count(substring) function, in this example, using this function, I will get the result "3". But I want the result "2". How can I achieve my goal, thanks in advance.
This will work just fine for any adjacent sub string:
a = "8448442844"
sol, sub = 0, "844"
for i in range(1, a.count(sub)+1):
if a.count(str(sub*i)): sol = i
else: break
print (sol)
# 2
Can also convert to a one-liner using Comprehension and sum:
a, sub = "8448442844", "844"
sol = sum([1 for x in range(1, a.count(sub)+1) if a.count(str(sub*x))])
# 2
Use str.count
>>> nStr = '000123000123'
>>> nStr.count('123')
2
Or use something like this
nStr = '000123000123'
pattern = '123'
count =0
flag=True
start=0
while flag:
a = nStr.find(pattern,start) # find() returns -1 if the word is not found,
#start i the starting index from the search starts(default value is 0)
if a==-1: #if pattern not found set flag to False
flag=False
else: # if word is found increase count and set starting index to a+1
count+=1
start=a+1
print(count)
U can try it like this. Maybe put it in a def. It works just fine
import string
s = "8448442844"
sub = "844"
max_sub = sub
count = 0
while string.find(s, max_sub) != -1:
max_sub = max_sub + sub
count +=1
print count
you can use a trick with str.split, itertools.groupby and max to get the result:
In [1]: import itertools
In [2]: "8448442844".split("844")
Out[2]: ['', '', '2', '']
In [3]: [len(list(lst)) for key, lst in itertools.groupby("8448442844".split("844")) if key == ""]
Out[3]: [2, 1]
In [4]: max([len(list(lst)) for key, lst in itertools.groupby("8448442844".split("844")) if key == ""])
Out[4]: 2

Creating my own string functions [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
def tlower(str1):
list = list(str1)
final = ''
for char in range(0,len(str1)):
if list[char] in UPPERCASE:
for ascii in range(0,len(UPPERCASE)):
if list[char] == UPPERCASE[ascii]:
list[char] = LOWERCASE[ascii]
final += list[char]
return final
NOTE - UPPERCASE and LOWERCASE are strings of all upper/lowercase letters
NOTE - can NOT use any string functions built into python (Replace, etc..)
I have this function to turn any string into all lower case, (Yes i know there is a built in function..) But compared to my other string functions I have created, this is fairly long, any better approach I should take to do doing this?
UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
LOWERCASE = "abcdefghijklmnopqrstuvwxyz"
def to_lower(s, trans=dict(zip(UPPERCASE, LOWERCASE))):
return ''.join(trans.get(ch,ch) for ch in s)
print to_lower('This Is a TEST') # => 'this is a test'
Edit:
zip() takes two lists and returns pairs of values, ie
zip('ABC', 'abc') # => [('A','a'), ('B','b'), ('C','c')]
dict() makes a dictionary - in this case,
{'A':'a', 'B':'b', 'C':'c'}
trans.get(x, y) is a more compact way of saying as trans[x] if x in trans else y. In this case, "if you have a lowercase version of this letter, return it, otherwise give back the original letter".
and if you don't like .join, how about reduce?
from operator import add
def to_lower(s, trans=dict(zip(UPPERCASE, LOWERCASE))):
return reduce(add, (trans.get(ch,ch) for ch in s), '')
For completeness:
def to_lower(string):
ords = (ord(c) for c in string)
return ''.join(chr(o + 32 * (65 <= o <= 90)) for o in ords)

Categories