(basic) Print each letter in Indexing - python

a = 'Hello World!'
print(a[0])
then I will get 'H'.
But is there any way I can get all the letters inside a seperately without typing print many times?

This code:
a = 'Hello World!'
print(*a, sep=" ")
will print:
H e l l o W o r l d !
This code:
a = 'Hello World!'
print(*a, sep="\n")
will print:
H
e
l
l
o
W
o
r
l
d
!

Are you asking how to iterate?
for letter in a:
print(letter, end='')
This assigns each item in the iterable a in turn to the variable letter for the duration of the indented block, and executes it as many times as there are items.
Equivalently, you can use an index into the string:
for idx in range(len(a)):
print(a[idx], end='')
range(n) simply produces the numbers 0, 1, 2, ... n-1 (you can optionally make it count from 0 or any other integer, in a different direction, etc).
If you want to keep a newline after each letter, you can take out the end='' keyword parameter.

Related

How to split string while keeping \n

I want to write the first letter of every item while linebreak stays the same but when I turn the list to string it's written in one line. Like this "I w t w f l o e I w l s s" but I want output to look like this "I w t \n w t f l \n o e i \n w l \n s s".
r = '''I want to
write the first letter
of every item
while linebreak
stay same'''
list_of_words = r.split()
m = [x[0] for x in list_of_words]
string = ' '.join([str(item) for item in m])
print(string)
What you are doing is you are splitting all the lines in a single go, so you are losing the information of each line. You need to create list of list to preserve the line information.
When you provide no argument means split according to any whitespace, that means both ' ' and '\n'.
r = '''I want to
write the first letter
of every item
while linebreak
stay same'''
list_of_words = [i.split() for i in r.split('\n')]
m = [[y[0] for y in x] for x in list_of_words]
string = '\n'.join([' '.join(x) for x in m])
print(string)
I w t
w t f l
o e i
w l
s s
Via regexp
r = '''I want to
write the first letter
of every item
while linebreak
stay same'''
import re
string = re.sub(r"(.)\S+(\s)", r"\1\2", r + " ")[:-1]
print(string)
Output:
I t
w t f l
o e i
w l
s s
What you're doing is - Get the first letter from each word
of the list and then joining them. You are not keeping track of the \n in the string.
You could do this instead.
list_of_words = r.split('\n')
m = [[x[0] for x in y.split()] for y in list_of_words]
for i in m:
string = ' '.join(i)
print(string)
Output
I w t
w t f l
o e i
w l
s s
Here is the solution by using while loop
r = '''I want to
write the first letter
of every item
while linebreak
stay same'''
total_lines = len(r.splitlines())
line_no = 0
while line_no < total_lines:
words_line = r.splitlines()[line_no]
list_of_words = words_line.split()
m = [x[0] for x in list_of_words]
print(' '.join([str(item) for item in m]))
line_no = line_no + 1
Since many valid methods were already provided, here's a nice and comprehensive way of doing the same task without the use of str.split(), which creates unnecessary list intermediates in memory (not that it represents any problem in this case though).
This method takes advantage of str.isspace() to deliver the whole set of instructions in one line:
string = "".join([string[i] for i in range(len(string)) if string[i].isspace() or string[i-1].isspace() or i == 0])

python alternative solution for split function

while bulls != 4:
userinput = list(map(int,input().split()))
for i in range(len(userinput)):
if userinput[i] == Guess[i]:
bulls += 1
So code is working for example when guess (it's a list) [1,2,3,4] and user input is 1 2 3 4.
Code is working only when user gives input with space (because of map(.split())) can you show me how can it work with an input without space character?
Because a string is an iterable, you can iterate over its characters.
If you want to split the user input after every digit, this can be done easily:
userinput = [int(c) for c in input()]
or to keep your original approach:
userinput = list(map(int, input()))
Both attempts result in userinput being the list of integers [1, 2, 3, 4, 5] if user entered 12345.
If you want it to work with or without spaces:
[int(c) for c in input() if c != ' ']
or:
list(map(int, filter(lambda c: c != ' ', input())))
You can iterate directly over the string, as that will yield each character individually. A string is an iterable of individual characters.
FWIW, you could write your code pretty succinctly like so:
for i, n in enumerate(int(c) for c in input() if c != ' '):
if n == guess[i]:
bulls += 1
See enumerate.
Or something like:
userinput = (int(c) for c in input() if c != ' ')
bulls += sum(n == g for n, g in zip(userinput, guess))

Python programming - beginner

so i have to create a code in which it reads every third letter and it creates a space in between each letter, my code creates the spaces but it also has a space after the last letter, this is my code:
msg = input("Message? ")
length = len(msg)
for i in range (0, length, 3):
x = msg[i]
print(x, end=" ")
My output was:
Message?
I enter:
cxohawalkldflghemwnsegfaeap
I get back
c h a l l e n g e
when the output isn't meant to have the last " " after the e.
I have read by adding print(" ".join(x)) should give me the output i need but when i put it in it just gives me a error. Please and Thank you
In Python, strings are one kind of data structures called sequences. Sequences support slicing, which is a simple and fancy way of doing things like "from nth", "to nth" and "every nth". The syntax is sequence[from_index:to_index:stride]. One does not even a for loop for doing that.ago
We can get every 3th character easily by omitting from_index and to_index, and have stride of 3:
>>> msg = input("Message? ")
cxohawalkldflghemwnsegfaeap
>>> every_3th = msg[::3]
>>> every_3th
'challenge'
Now, we just need to insert spaces after each letter. separator.join(iterable) will join elements from iterable together in order with the given separator in between. A string is an iterable, whose elements are the individiual characters.
Thus we can do:
>>> answer = ' '.join(every_3th)
>>> answer
'c h a l l e n g e'
For the final code we can omit intermediate variables and have still a quite readable two-liner:
>>> msg = input('Message? ')
>>> print(' '.join(msg[::3]))
Try
>>> print " ".join([msg[i] for i in range(0, len(msg), 3)])
'c h a l l e n g e'

Python fastest way to remove single spaces from spaced out letters in string

I have a document with some lines that have spaced out letters which I want to remove.
The problem is, that the strings are not following all the same rules. So I have some with just one space, also between the words and some with two or three speaces between the words
Examples:
"H e l l o g u y s"
"H e l l o g u y s"
"H e l l o g u y s"
all the above should be converted to --> "Hello guys"
"T h i s i s P a g e 1" --> "This is Page 1"
I wrote a script to remove every second space but not if next letter is numeric or capital. It's working almost OK, since the processed text is German and almost every time the words begin with capital letters... almost.
Anyways I'm not satisfied with it. So I'm asking if there is a neat function for my problem.
text = text.strip() # remove spaces from start and end
out = text
if text.count(' ') >= (len(text)/2)-1:
out = ''
idx = 0
for c in text:
if c != ' ' or re.match('[0-9]|\s|[A-Z0-9ÄÜÖ§€]', text[idx+1]) or (idx > 0 and text[idx-1] == '-'):
out += c
idx += 1
text = out
Not the most original answer but I've seen that your problem almost matches this one.
I have taken unutbu's answer, slightly modified it to solve your queries with enchant. If you have any other dictionary, you can use that instead.
import enchant
d = enchant.Dict("en_US") # or de_DE
def find_words(instring, prefix = ''):
if not instring:
return []
if (not prefix) and (d.check(instring)):
return [instring]
prefix, suffix = prefix + instring[0], instring[1:]
solutions = []
# Case 1: prefix in solution
if d.check(prefix):
try:
solutions.append([prefix] + find_words(suffix, ''))
except ValueError:
pass
# Case 2: prefix not in solution
try:
solutions.append(find_words(suffix, prefix))
except ValueError:
pass
if solutions:
return sorted(solutions,
key = lambda solution: [len(word) for word in solution],
reverse = True)[0]
else:
raise ValueError('no solution')
inp = "H e l l o g u y s T h i s i s P a g e 1"
newInp = inp.replace(" ", "")
print(find_words(newInp))
This outputs:
['Hello', 'guys', 'This', 'is', 'Page', '1']
The linked page certainly is a good starting point for some pragmatic solutions. However, I think a proper solution should use n-grams. This solution could be modified to make use of multiple whitespaces as well, since they might indicate the presence of a word boundary.
Edit:
You can also have a look at Generic Human's solution using a dictionary with relative word frequencies.
You can check whether a word is a english word and then split the words. You could use a dedicated spellchecking library like PyEnchant.
For example:
import enchant
d = enchant.Dict("en_US")
d.check("Hello")
This will be a good starter. But there is the problem with "Expertsexchange".
Converting "H e l l o g u y s" might be very hard or not under the scope of this site. but if you wont to convert the strings like "H e l l o g u y s" or other that the number of spaces between words is different from spaces between letters you can use a the following code :
>>> import re
>>> s1="H e l l o g u y s"
>>> s2="H e l l o g u y s"
>>> ' '.join([''.join(i.split()) for i in re.split(r' {2,}',s2)])
'Hello guys'
>>> ' '.join([''.join(i.split()) for i in re.split(r' {2,}',s1)])
'Hello guys'
this code use a regular expression (' {2,}') for split the words . that split the string from where that have more than 2 spaces !
Demo
This is an algorithm that could do it. Not battle-tested, but just an idea.
d = ['this', 'is', 'page', 'hello', 'guys']
m = ["H e l l o g u y s", "T h i s i s P a g e 1", "H e l l o g u y s", "H e l l o g u y s"]
j = ''.join(m[0].split()).lower()
temp = []
fix = []
for i in j:
temp.append(i)
s = ''.join(temp)
if s in d:
fix.append(s)
del temp[:]
if i.isdigit():
fix.append(i)
print(' '.join(fix))
Prints the following:
this is page 1, hello guys with your supplied test inputs.
Extending
You can use this dictionary which has words on each line, convert it to a list and play around from there.
Issues
As Martjin suggested, what would you do when you encounter "E x p e r t s e x c h a n g e". Well, in such scenarios, using n-gram probabilities would be an appropriate solution. For this you would have to look into NLP (Natural Language Processing) but I assume you don't want to go that far.
You cannot do this - the situation where valid word boundaries are represented the same way as spaces which should be removed is theoretically the same situation where you have no spaces at all in the text.
So you can "reduce" your problem to the problem of re-inserting word boundary spaces in a text with no spaces at all - which is just as impossible, because even with a dictionary containing every valid word - which you do not have -, you can either go for a greedy match and insert too few spaces, or go for a non-greedy match and insert too many.

Having trouble with whitespace and strings in a function

Prompt
Turn a string into rollercoaster case. The first letter of the sentence is uppercase, the next lowercase, the next uppercase, and so on.
Code
with open('test.txt') as file:
for line in file:
words = line.split()
for word in words:
chars = list(word)
for index, char in enumerate(chars):
if index == 0:
print char.upper(),
elif is_even(index):
print char.upper(),
elif is_odd(index):
print char,
Input
Sunshine makes me happy, on a cloudy day
Output
S u N s H i N e M a K e S M e H a P p Y , O n A C l O u D y D a Y
This is my first attempt at this problem. I can't think of any other way to do this other than to iterate by each letter. When I do this though I'm just treating the entire sentence as a string and spewing out characters.
You can uppercase just every second letter with an extended slice, picking every second letter:
>>> sample = 'Sunshine makes me happy, on a cloudy day'
>>> sample[::2].upper()
'SNHN AE EHPY NACOD A'
>>> sample[1::2].lower()
'usiemksm ap,o luydy'
Now all you need to do is put those together again:
from itertools import izip_longest
result = ''.join([l
for pair in izip_longest(sample[::2].upper(), sample[1::2].lower(), fillvalue='')
for l in pair])
izip_longest() pairs up the uppercased and lowercased strings again, making sure that if there is an odd number of characters to pad out the series with an empty string.
Demo:
>>> from itertools import izip_longest
>>> ''.join([l
... for pair in izip_longest(sample[::2].upper(), sample[1::2].lower(), fillvalue='')
... for l in pair])
'SuNsHiNe mAkEs mE HaPpY, oN A ClOuDy dAy'
Note that whitespace isn't ignored here; the m of make is lowercased even though the e at the end of Sunshine is too.
If you need to vary the letters more precisely, you can make use of iteration still:
from itertools import cycle
from operator import methodcaller
methods = cycle((methodcaller('upper'), methodcaller('lower')))
result = ''.join([next(methods)(c) if c.isalpha() else c for c in sample])
Here itertools.cycle() lets us alternate between two operator.methodcaller() objects, which either upper or lowercase the argument passed in. We only advance to the next one (using next()) when the character is a letter.
Demo:
>>> from itertools import cycle
>>> from operator import methodcaller
>>> methods = cycle((methodcaller('upper'), methodcaller('lower')))
>>> ''.join([next(methods)(c) if c.isalpha() else c for c in sample])
'SuNsHiNe MaKeS mE hApPy, On A cLoUdY dAy'
If it's whitespace giving you trouble, you should use isalpha() to test if a character is a letter or not.
with open('test.txt') as file:
for line in file:
newstr = ""
go_to_upper = True
for c in line:
if c.isalpha():
if go_to_upper:
newstr += c.upper()
else:
newstr += c.lower()
go_to_upper = not go_to_upper
else:
newstr += c
print newstr
Input: Sunshine makes me happy, on a cloudy day
Output: SuNsHiNe MaKeS mE hApPy, On A cLoUdY dAy
You'll only flip back and forth (using the go_to_upper boolean) when the character in question is a letter of the alphabet. Otherwise, it's outputted normally. Notice that MaKeS starts with a capital letter, though SuNsHiNe ends with a lowercase letter, even with the space in the way.
Also, instead of printing immediately (which gives you the weird spacing) we're putting our characters in a new list, which we'll print out all at once later.
Try this code :
import re
i = 1
with open('test.txt') as file:
for line in file:
words = line.split()
for word in words:
chars = list(word)
for index, char in enumerate(chars):
if re.compile('[a-zA-Z]').search(char):
i+=1
if i%2 !=0:
print char.upper(),
else :
print char.lower(),

Categories

Resources