Add ": " for every nth character in a list - python

Say i have this:
x = ["hello-543hello-454hello-765", "hello-745hello-635hello-321"]
how can i get the output to:
["hello-543: hello-454: hello-765", "hello-745: hello-635: hello-321"]

You can split each string based on substring length with a list comprehension using range where the step value is the number of characters each substring should contain. Then use join to convert each list back to a string with the desired separator characters.
x = ["hello-543hello-454hello-765", "hello-745hello-635hello-321"]
n = 9
result = [': '.join([s[i:i+n] for i in range(0, len(s), n)]) for s in x]
print(result)
# ['hello-543: hello-454: hello-765', 'hello-745: hello-635: hello-321']
Or with textwrap.wrap:
from textwrap import wrap
x = ["hello-543hello-454hello-765", "hello-745hello-635hello-321"]
n = 9
result = [': '.join(wrap(s, n)) for s in x]
print(result)
# ['hello-543: hello-454: hello-765', 'hello-745: hello-635: hello-321']

If you are sure every str length is multiply of your n, I would use re.findall for that task.
import re
txt1 = "hello-543hello-454hello-765"
txt2 = "hello-745hello-635hello-321"
out1 = ": ".join(re.findall(r'.{9}',txt1))
out2 = ": ".join(re.findall(r'.{9}',txt2))
print(out1) #hello-543: hello-454: hello-765
print(out2) #hello-745: hello-635: hello-321
.{9} in re.findall mean 9 of any characters excluding newline (\n), so this code would work properly as long as your strs do not contain \n. If this does not hold true you need to add re.DOTALL as third argument of re.findall

Related

Trying to take a sentence with numbers and change the numbers into words. then print the sentence wit the changes

change the numaruls into the word
list_of_nums =["zero","one","two","three","four","five","six","seven","eight","nine"]
text = "2 apples and 6 pears"
a = text.split()
text_splt = []
for x in a:
if x in list_of_nums:
text = text.replace(x,text_splt[list_of_nums(x)])
print(text)
I also tried
arr.append(a)
print(arr)
print(list_of_nums)
arr.insert(0,list_of_nums[2])
print(arr)
need the index of the first array to compare to the value of whats index in the second array
but this ended in a error
You can loop over the list of numbers and replace each index with the word at that index.
for i, x in enumerate(list_of_nums):
text = text.replace(str(i), x)
You could also use a regular expression to match single digits.
import re
text = re.sub(r'\b\d\b', lambda m: list_of_nums[int(m.group())], text)

Is there a way of splitting a word into 3 different parts in python?

char = "RV49CJ0AUTS172Y"
To get this output:
separated = "RV49C-J0AUT-S172Y"
I have tried:
split_strings = []
n = 5
for index in range(0, len(name), n):
split_strings.append(name[index : index + n])
But that did not go as I wanted
This shows a good method but I want them on the same line with dashes between them
You can do it in one-line, using re
import re
string = "RV49CJ0AUTS172Y"
separated = "-".join(re.findall('.{%d}' % (len(string) / 3), string))
print(separated)
[Output]
RV49C-J0AUT-S172Y
Your code almost works, just calculate the amount of characters needed (n) instead of hard-coding it to 5. And for the final result, use "-".join(...) to mix all the elements of the array together into a single string.
char = "RV49CJ0AUTS172Y"
split_strings = []
n = len(char) // 3
for index in range(0, len(char), n):
split_strings.append(char[index: index + n])
print("-".join(split_strings))

How can I shift patterns in a string one place ahead (removing the first, replacing the last)?

I have a string in Python, and I would like to shift a pattern 1 place earlier.
This is my string:
my_string = [AudioLengthInSecs: 37.4]hello[seconds_silence:
0.65]one[seconds_silence: 0.54]two[seconds_silence: 0.59]three[seconds_silence:
0.48]hello[seconds_silence: 2.32]
I would like to shift the numbers, after [seconds_silence: XXXX] one place earlier (and removing the first one, and the last one (since that one is shifted)). The result should be like this:
my_desired_string = [AudioLengthInSecs: 37.4]hello[seconds_silence: 0.54]one[seconds_silence: 0.59]two[seconds_silence:
0.48]three[seconds_silence: 2.32]hello
Here is my code:
import re
my_string = "[AudioLengthInSecs: 37.4]hello[seconds_silence:0.65]one[seconds_silence: 0.54]two[seconds_silence: 0.59]three[seconds_silence: 0.48]hello[seconds_silence: 2.32]"
# First, find all the numbers in the string
all_numbers = (re.findall('\d+', my_string ))
# Secondly, remove the first 4 numbers ()
all_numbers = all_numbers[4:]
# combine the numbers into one string
all_numbers
combined_numbers = [i+j for i,j in zip(all_numbers[::2], all_numbers[1::2])]
# Than loop over the string and instert
for word in my_string.split():
print(word)
if word == "[seconds_silence":
print(word)
# here i wanted to check if [soconds_silence was recognized
# and replace with value from combined_numbers
# however, this is failing obviously
The idea is to find all pairs:
the string preceding [seconds_silence: ...] fragment (capturing group No 1),
and the above fragment itself (capturing group No 2).
Then:
drop the first [seconds_silence: ...] fragment,
and join both lists,
but as they now have different length, itertools.zip_longest is needed.
So the whole code to do your task is:
import itertools
import re
my_string = '[AudioLengthInSecs: 37.4]hello[seconds_silence:0.65]'\
'one[seconds_silence: 0.54]two[seconds_silence: 0.59]'\
'three[seconds_silence: 0.48]hello[seconds_silence: 2.32]'
gr1 = []
gr2 = []
for mtch in re.findall(r'(.+?)(\[seconds_silence: ?[\d.]+\])', my_string):
g1, g2 = mtch
gr1.append(g1)
gr2.append(g2)
gr2.pop(0)
my_desired_string = ''
for g1, g2 in itertools.zip_longest(gr1, gr2, fillvalue=''):
my_desired_string += g1 + g2
print(my_desired_string)

Python string split join 4

import re
string = "is2 Thi1s T4est 3a"
def order(sentence):
res = ''
count = 1
list = sentence.split()
for i in list:
for i in list:
a = re.findall('\d+', i)
if a == [str(count)]:
res += " ".join(i)
count += 1
print(res)
order(string)
Above there is a code which I have problem with. Output which I should get is:
"Thi1s is2 3a T4est"
Instead I'm getting the correct order but with spaces in the wrong places:
"T h i 1 si s 23 aT 4 e s t"
Any idea how to make it work with this code concept?
You are joining the characters of each word:
>>> " ".join('Thi1s')
'T h i 1 s'
You want to collect your words into a list and join that instead:
def order(sentence):
number_words = []
count = 1
words = sentence.split()
for word in words:
for word in words:
matches = re.findall('\d+', word)
if matches == [str(count)]:
number_words.append(word)
count += 1
result = ' '.join(number_words)
print(result)
I used more verbose and clear variable names. I also removed the list variable; don't use list as a variable name if you can avoid it, as that masks the built-in list name.
What you implemented comes down to a O(N^2) (quadratic time) sort. You could instead use the built-in sort() function to bring this to O(NlogN); you'd extract the digit and sort on its integer value:
def order(sentence):
digit = re.compile(r'\d+')
return ' '.join(
sorted(sentence.split(),
key=lambda w: int(digit.search(w).group())))
This differs a little from your version in that it'll only look at the first (consecutive) digits, it doesn't care about the numbers being sequential, and will break for words without digits. It also uses a return to give the result to the caller rather than print. Just use print(order(string)) to print the return value.
If you assume the words are numbered consecutively starting at 1, then you can sort them in O(N) time even:
def order(sentence):
digit = re.compile(r'\d+')
words = sentence.split()
result = [None] * len(words)
for word in words:
index = int(digit.search(word).group())
result[index - 1] = word
return ' '.join(result)
This works by creating a list of the same length, then using the digits from each word to put the word into the correct index (minus 1, as Python lists start at 0, not 1).
I think the bug is simply in the misuse of join(). You want to concatenate the current sorted string. i is simply a token, hence simply add it to the end of the string. Code untested.
import re
string = "is2 Thi1s T4est 3a"
def order(sentence):
res = ''
count = 1
list = sentence.split()
for i in list:
for i in list:
a = re.findall('\d+', i)
if a == [str(count)]:
res = res + " " + i # your bug here
count += 1
print(res)
order(string)

Python replace 3 random characters in a string with no duplicates

I need change 3 random characters in a string using Python, example string:
Adriano Celentano
Luca Valentina
I need to replace 3 characters, not replacing with the same character or number, not replacing space. How can I do this using Python ?
Need output like this :
adraano cettntano
lacr vilenntina
I don't know from where i can start to make this.
My code so far:
for i in xrange(4):
for n in nume :
print n.replace('$', random.choice(string.letters)).replace('#', random.choice(string.letters))
If you just want to change chars that are not whitespace and not the same char in regards to index, you can first pull the indexes where the non-whitespace chars are:
import random
inds = [i for i,_ in enumerate(s) if not s.isspace()]
print(random.sample(inds,3))
Then use those indexes to replace.
s = "Adriano Celentano"
import random
inds = [i for i,_ in enumerate(s) if not s.isspace()]
sam = random.sample(inds, 3)
from string import ascii_letters
lst = list(s)
for ind in sam:
lst[ind] = random.choice(ascii_letters)
print("".join(lst))
If you want a unique char each time to replace with also:
s = "Adriano Celentano"
import random
from string import ascii_letters
inds = [i for i,_ in enumerate(s) if not s.isspace()]
sam = random.sample(inds, 3)
letts = iter(random.sample(ascii_letters, 3))
lst = list(s)
for ind in sam:
lst[ind] = next(letts)
print("".join(lst))
output:
Adoiano lelenhano
You can do this in two stages. In the first stage you pick 3 random positions in your string that meet your search criteria (isalnum):
import random
import string
replacement_chars='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
# replacement_chars = string.letters + string.digits
input = 'Adriano Celentano'
input_list = list(input)
input_dic = dict(enumerate(input_list))
valid_positions=[key for key in input_dic if input_dic[key].isalnum()]
random_positions=random.sample(valid_positions,3)
In the second part you generate 3 random characters and replace the characters in the previously selected positions. I have added a while loop to generate a new random character if it matches the existing value
random_chars = random.sample(replacement_chars,len(random_positions))
char_counter = 0
for position in random_positions:
#check if the replacement character matches the existing one
#and generate another one if needed
while input_list[position]==random_chars[char_counter]:
random_chars[char_counter] = random.choice(replacement_chars)
input_list[position]=random_chars[char_counter]
char_counter = char_counter + 1
print "".join(input_list).lower()

Categories