Print every two letters pairs in python3 - python

I'm new to Python and I'm stuck in an exercise which tells me to provide a script printing every possible pairs of two letters, only lower case, one by line, ordered alphabetically and that is the closest thing that I could do
import string
x=string.ascii_lowercase
y=list(x)
for i in y:
print(i,end='')
for g in y:
print(g)

You only print the first letter of each pair once.
from string import ascii_lowercase as lowercase_letters
for first_letter in lowercase_letters:
for second_letter in lowercase_letters:
print(first_letter + second_letter)
Additionally:
You don't need to convert the string to a list, you can loop over a string just fine. In fact, that's how list(some_string) works!
I used more readable variable names.
Using from ... import means you don't need to have the additional assignment.

You need to print the i letter in the second for loop
import string
x=string.ascii_lowercase
for i in x:
for g in x:
print(i,g)
So the program will go through every letter in the first loop and will print then the whole alphabet, one by one, as the second letter in the second loop

word_list = ['WELCOME']
double_letters = []
for word in word_list:
for i,j in enumerate(word):
x = word[i:i+2]
if len(x) == 2:
double_letters.append(x)
print(double_letters)
If you are given a list of words. Then this is one possible way

Try this code this will print in alphabetic order
You have studied ASCII code so what it does is it loops through 97 to 122 which contains all the alphabets and then it joins them.
for firstchar in range(97, 123):
for secondchar in range(97, 123):
print(chr(firstchar) + chr(secondchar))

If use string module it is very simple task:
import string
for firstchar in string.ascii_lowercase:
for secondchar in string.ascii_lowercase:
print(firstchar + secondchar)

Related

Alphabet position in python

Newbie here...Trying to write a function that takes a string and replaces all the characters with their respective dictionary values.
Here is what I have:
def alphabet_position(text):
dict = {'a':'1','b':'2','c':'3','d':'4','e':'5','f':'6','g':'7','h':'8':'i':'9','j':'10','k':'11','l':'12','m':'13','n':'14','o':'15','p':'16','q':'17','r':'18','s':'19','t':'20','u':'21','v':'22','w':'23','x':'24','y':'25','z':'26'}
text = text.lower()
for i in text:
if i in dict:
new_text = text.replace(i, dict[i])
print (new_text)
But when I run:
alphabet_position("The sunset sets at twelve o' clock.")
I get:
the sunset sets at twelve o' cloc11.
meaning it only changes the last character in the string. Any ideas? Any input is greatly appreciated.
Following your logic you need to create a new_text string and then iteratively replace its letters. With your code, you are only replacing one letter at a time, then start from scratch with your original string:
def alphabet_position(text):
dict = {'a':'1','b':'2','c':'3','d':'4','e':'5','f':'6','g':'7','h':'8','i':'9','j':'10','k':'11','l':'12','m':'13','n':'14','o':'15','p':'16','q':'17','r':'18','s':'19','t':'20','u':'21','v':'22','w':'23','x':'24','y':'25','z':'26'}
new_text = text.lower()
for i in new_text:
if i in dict:
new_text = new_text.replace(i, dict[i])
print (new_text)
And as suggested by Kevin, you can optimize a bit using set. (adding his comment here since he deleted it: for i in set(new_text):) Note that this might be beneficial only for large inputs though...
As your question is generally asking about "Alphabet position in python", I thought I could complement the already accepted answer with a different approach. You can take advantage of Python's string lib, char to int conversion and list comprehension to do the following:
import string
def alphabet_position(text):
alphabet = string.ascii_lowercase
return ''.join([str(ord(char)-96) if char in alphabet else char for char in text])
Your approach is not very efficient. You are recreating the string for every character.
There are 5 e characters in your string. This means replace is called 5 times, even though it only actually needs to do anything the first time.
There is another approach that might be more efficient. We cant use str.translate unfortunately, as it's remit is one to one replacements.
We just iterate the input and produce a new string character by character.
def alphabet_position2(text):
d = {L: str(i) for i, L in enumerate('abcdefghijklmnopqrstuvwxyz', 1)}
result = ''
for t in text.lower():
result += d.get(t, t)
return result
This is a pretty simple approach with list comprehension.
Generate k:v in this format from string module, 1:b instead of b:1
import string
def alphabet_position(text):
alphabeths = {v: k for k, v in enumerate(string.ascii_lowercase, start=1)}
return " ".join(str(alphabeths.get(char)) for char in text.lower() if char in alphabeths.keys())

how do i make a python program check if a there is a letter from a string in a string

I am trying to make the python program check if at least one letter is in a string?
import string
s = ('hello')
if string.ascii_lowercase in s:
print('yes')
else:
print('no')
It always just prints no
Well, string.ascii_lowercase is equal to 'abcdefghijklmnopqrstuvwxyz'. That doesn't look like it's contained in hello, right?
What you should do instead is to go over the letters in ascii_lowercase and check if any of them are in your string s.
import string
s = ('hello')
if any([letter in s for letter in string.ascii_lowercase]):
print('yes')
else:
print('no')
Wonderfully smart people in the comments have pointed out that you can drop the [ ] brackets that would usually create a list, turning our list comprehension into something called a generator. This would prevent the need to check every single letter in ascii_lowercase and make our code a little bit faster - as it stands, the whole list is generated and then checked. With the generator, the letters are checked only up to e, as that's in 'hello'.
I was able to shave off a whole nanosecond this way! Still, straight up going through the whole list should be fine as well for most cases and is certainly simpler.
An efficient way to check if some string s contains any character from some alphabet:
alphabet = frozenset(string.ascii_lowercase)
any(letter in alphabet for letter in s)
Key points:
Avoid linear search by storing the alphabet in a set instead of a more general iterable that doesn't allow fast (O(1)) check of elements
Loop over the input, not the target alphabet, because the alphabet is probably a finite set of constant size, and allow even very large inputs efficiently, without linear searching and excessive memory use (putting input in a set instead of the alphabet)
Avoid unnecessary list creation (and wasted memory) by using a generator expression
Here are some inferior alternatives.
Linear search over string.ascii_lowercase:
any(letter in string.ascii_lowercase for letter in s)
Linear search over string.ascii_lowercase, and a useless list creation:
any([letter in string.ascii_lowercase for letter in s])
Linear search over the input, very poor performance in the worst case when the input is very long and does not contain any character from the alphabet:
any(letter in s for letter in string.ascii_lowercase)
Currently you are checking whether the whole string string.ascii_lowercase is in s.
You have to check every single character of string.ascii_lowercase instead.
The naive solution would look like this:
>>> s = 'hello'
>>> for letter in string.ascii_lowercase:
... if letter in s:
... print('yes')
... break
... else:
... print('no')
...
yes
Here, the else block will only execute if the loop was not broken by the break statement.
A shorthand for the for loop would be to use the any builtin paired with a generator-expression:
>>> contained = any(letter in s for letter in string.ascii_lowercase)
>>> print('yes' if contained else 'no')
yes
Finally, you can improve the runtime of both implementations by using the set of characters from s, i.e. s = set(s). This will ensure that every in check is performed in constant time rather than iterating over s for every letter that is searched.
edit: Here's another short one:
>>> if set(s).intersection(string.ascii_lowercase):
... print('yes')
... else:
... print('no')
...
yes
This uses the fact that an empty set (the possible result of the intersection) will be treated as False in the if check.
(It has the slight drawback that the computation of the intersection does not stop once a single shared letter letter is found.)
Make a set of each string and check the size of their intersection
def share_letter(s1, s2):
return bool(set(s1).intersection(s2))
string.ascii_lowercase is a string that contains all the lower case alphabets, i.e abcdefghijklmnopqrstuvwxyz.
So, in the if condition, if string.ascii_lowercase in s you are checking if the string contains a substring abcdefghijklmnopqrstuvwxyz.
You can try this,
if any(e in string.ascii_lowercase for e in s):
...
The expression inside any is a generator, thus it stop checking at the first match.
Another way to do this is,
if any(e.islower() for e in s):
...
This is another option:
import string
s = ('hello')
alpha = string.ascii_lowercase
if any(i in alpha for i in s):
print('yes')
else:
print('no')
Or maybe quicker:
import string
s = ('hello')
alpha = string.ascii_lowercase
for l in s:
if l in alpha:
print("yes")
break
print("no")

Subscripting an Array of Integers in Python?

I'm absolutely terrible at Python and my Computer Programming class ends in two days (thank god), but I am having the hardest time figuring out what is probably the easiest code ever.
The instructions to my assignment state, "Write a program which reads in text until a '!' is found. Use an array of integers subscripted by the letters 'A' through 'Z'."
From what i have done so far:
msg = input("What is your message? ")
msg = msg.upper()
int_array = [0] * 26
for alph in range (65, 91):
char = chr(alph)
print(char)
(int_array[char])
any help would be greatly appreciated! thanks!
EDIT: This is the full assignment:
Write a program which reads in text from the keyboard until a ('!') is found.
Using an array of integers subscripted by the letters 'A' through 'Z', count the number occurrences of each letter (regardless of whether it is upper or lower case). In a separate counter, also count the total number of "other" characters ('.', '?', ' ', '2', etc.).
Print out the count for each letter found. Also, print the count of the non-letter characters.
By inspecting the array, print out the count of the number of vowels, and the number of consonants.
Print out which letter was found the most times. (Note there may be more than one letter which has the maximum count attached to it.) Print out which letter (or letters) was found the least number of times, but make certain to exclude letters which were not found at all.
UPDATE:
I have gotten this far with my code
msg = input("What is your message? ")
print ()
num_alpha = 26
int_array = [0] * num_alpha
for alpha in range(num_alpha):
int_array[alpha] = chr(alpha + 65)
print(int_array[alpha], end = "")
print()
lett = 0
otherch = 0
num_vowels = 0
num_consanants = 0
count_character = [0] * 100000
length = len(msg)
for character in msg.upper():
if character == "!":
print("lett =", lett)
print("other char = ", otherch)
print("num_vowels = ", num_vowels)
print("num_consanants = ", num_consanants)
elif character < "A" or letter > "Z":
otherch = otherch + 1
count_character[ord(character)] = count_character[ord(character)] + 1
else:
lett = lett + 1
count_character[ord(character)] = count_character[ord(character)] + 1
for character in msg:
print("character", character, "appeared" , count_character[ord(character)] , "times")
it's obviously not finished yet, but every time i print the last print statement, it says that each character appeared 0 times. can anybody help?
You're going to need to get clarification on this, because there's no such thing as "an array of integers subscripted by the letters 'A' through 'Z'" in Python.
Possible interpretations that I can think of:
It's supposed to be a dictionary rather than an array. Python dictionaries are similar to lists (the Python datatype that is roughly equivalent to "arrays" in other languages), but they can be subscripted by strings, whereas lists can be subscripted only by integers. This way, you can store an integer to be associated with each letter. This is how most Python programmers would generally do something like this.
You're supposed to use parallel lists. You can do this by making two lists of 26 elements each, one containing the letters 'A' through 'Z' and one containing integers. For each letter, you could then use the list.index method to find the index in the first list where that letter is, then look up that index in the second list. (In theory, you wouldn't really need the first list, since Python strings are like lists in that they can be subscripted with integers and support the index method. So you could use the string 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' instead of a list. Or you could use the ord function, which is the inverse of the chr function. But I don't know if you're supposed to use these features.)
I'm not 100% sure the following is right because I agree with the others that the assignment description is wonky. It looks like a C-based homework assignment lazily ported to Python. That said:
In principle rather than hardcoding the bounds of the alphabet I'd go with ord('A') and ord('Z')+1, so that I can say something like alphabet = list(range(ord('A'), ord('Z')+1))
Renaming int_array to counter might make it more obvious what you need to do in your inner loop (keeping in mind that you're using the letters as your indices. Or rather, you'd need something more like ord(letter)-ord('A') as your indices)
You don't want to loop over the alphabet; you want to loop over the input.
count should be initialized to [0]*27 to track "other" values. You can increment counter[-1] for non-alphabetic characters.
Your final value is chr of counter.index(max(counter)). You may find it more straightforward, or your teacher may find it more acceptable, to just write a for loop.

Rm duplication in list comprehension

Input is a string, the idea is to count the letters A-z only, and print them alphabetically with the count of appearances.
As usual I kept at this 'till I got a working result, but now seek to optimize it in order to better understand the Python way of doing things.
def string_lower_as_list(string):
"""
>>> string_lower_as_list('a bC')
['a', ' ', 'b', 'c']
"""
return list(string.lower())
from sys import argv
letters = [letter for letter in string_lower_as_list(argv[1])
if ord(letter) < 124 and ord(letter) > 96]
uniques = sorted(set(letters))
for let in uniques:
print let, letters.count(let)
How do I remove the duplication of ord(letter) in the list comprehension?
Would there have been any benefit in using a Dictionary or Tuple in this instance, if so, how?
EDIT
Should have said, Python 2.7 on win32
You can compare letters directly and you actually only need to compare lower case letters
letters = [letter for letter in string_lower_as_list(argv[1])
if "a" <= letter <= "z"]
But better would be to use a dictionary to count the values. letters.count has to traverse the list every time you call it. But you are already traversing the list to filter out the right characters, so why not count them at the same time?
letters = {}
for letter in string_lower_as_list(argv[1]):
if "a" <= letter <= "z":
letters[letter] = letters.get(letter, 0) + 1
for letter in sorted(letters):
print letter, letters[letter]
Edit: As the others said, you don't have to convert the string to a list. You can iterate over it directly: for letter in argv[1].lower().
How do I remove the duplication of ord(letter) in the list comprehension?
You can use a very Python-specific and somewhat magical idiom that doesn't work in other languages: if 96 < ord(letter) < 124.
Would there have been any benefit in using a Dictionary or Tuple in this instance, if so, how?
You could try using the collections.Counter class added in Python 2.7.
P.S. You don't need to convert the string to a list in order to iterate over it in the list comprehension. Any iterable will work, and strings are iterable.
P.S. 2. To get the property 'this letter is alphabetic', instead of lowercasing and comparing to a range, just use str.isalpha. Unicode objects provide the same method, which allows the same code to Just Work with text in foreign languages, without having to know which characters are "letters". :)
You don't have to convert string to list, string is iterable:
letters = {}
for letter in argv[1].lower():
if "a" <= letter <= "z":
letters[letter] = letters.get(letter, 0) + 1
for letter in sorted(letters.keys()):
print letter, letters[letter]

In Python, how do I create a string of n characters in one line of code?

I need to generate a string with n characters in Python. Is there a one line answer to achieve this with the existing Python library? For instance, I need a string of 10 letters:
string_val = 'abcdefghij'
To simply repeat the same letter 10 times:
string_val = "x" * 10 # gives you "xxxxxxxxxx"
And if you want something more complex, like n random lowercase letters, it's still only one line of code (not counting the import statements and defining n):
from random import choice
from string import ascii_lowercase
n = 10
string_val = "".join(choice(ascii_lowercase) for i in range(n))
The first ten lowercase letters are string.lowercase[:10] (if you have imported the standard library module string previously, of course;-).
Other ways to "make a string of 10 characters": 'x'*10 (all the ten characters will be lowercase xs;-), ''.join(chr(ord('a')+i) for i in xrange(10)) (the first ten lowercase letters again), etc, etc;-).
if you just want any letters:
'a'*10 # gives 'aaaaaaaaaa'
if you want consecutive letters (up to 26):
''.join(['%c' % x for x in range(97, 97+10)]) # gives 'abcdefghij'
Why "one line"? You can fit anything onto one line.
Assuming you want them to start with 'a', and increment by one character each time (with wrapping > 26), here's a line:
>>> mkstring = lambda(x): "".join(map(chr, (ord('a')+(y%26) for y in range(x))))
>>> mkstring(10)
'abcdefghij'
>>> mkstring(30)
'abcdefghijklmnopqrstuvwxyzabcd'
This might be a little off the question, but for those interested in the randomness of the generated string, my answer would be:
import os
import string
def _pwd_gen(size=16):
chars = string.letters
chars_len = len(chars)
return str().join(chars[int(ord(c) / 256. * chars_len)] for c in os.urandom(size))
See these answers and random.py's source for more insight.
If you can use repeated letters, you can use the * operator:
>>> 'a'*5
'aaaaa'

Categories

Resources