I'm wondering if it's possible to take a string e.g. str(input()) and split it into individual chars, then add them to a list. I'm trying to make a simple script (something similar to a hangman game) and at the beginning I wrote this:
x=input('Choose word: ').lower()
letters=[]
letters.append(list(x))
print(letters)
but this code appends the whole list to a list and not individual chars
Edit: this outputs [['o', 'u', 't', 'p', 'u', 't']] meaning that the whole list got appended as one item, but I want this to output ['o', 'u', 't', 'p', 'u', 't'], how do I make it append individual chars and not the whole list
You are simply wrapping the char list in another list.
Try this one-liner instead:
print(list(x))
If you want to remove a character:
letters = list(x)
letters.remove('o')
print(letters)
Use extend instead of append function.
#Extend
x=input('Choose word: ').lower()
letters=[]
letters.extend(list(x))
print(letters)
# ['p', 'y', 't', 'h', 'o', 'n']
And to remove a character from a list while retaining position as blank after removing, use replace while within a list:
y=input("Choose a letter to remove: ").lower()
removed=[s.replace(y,'') for s in letters]
print(removed)
#['p', '', 't', 'h', 'o', 'n']
I hope this help, unless its different from what you want. Then let me know. Otherwise, happy coding!
You don't need to create an empty list and then populate it with individual letters. Simply apply the list() function directly for the user input to create it:
letters = list(input('Choose word: ').lower())
print(letters)
For adding letters from the other user input, use the same approach with the .extend() method:
letters.extend(input('Choose word: ').lower()) # No need to use list() here
A simple one liner:
x = input().lower().split()
print(x)
here we are taking the input and then we are converting to lowercase and then using the split function which will split the string on white spaces you can split the string on whatever string you feel like just give the string you want to split on as the argument in the split function for example:
x = input().lower().split(',')
print(x)
this will split on the ',' so you can give the input in csv format
You may use the + operator (preferably in the form of an augmented assignment statement, i.e. +=, for extending the list to an iterable.
No need to use the list() function here, because the string is iterable:
letters = []
letters += input('Choose word: ').lower()
print(letters)
this outputs [['o', 'u', 't', 'p', 'u', 't']] meaning that the whole
list got appended as one item, but i want this to output ['o', 'u', 't', 'p', 'u', 't']
Based on you comment, you can use:
x = [*input('Choose word: ').lower()]
print(x)
# ['p', 'y', 't', 'h', 'o', 'n']
Demo
Related
I was hoping someone could explain this behaviour to me and what is going on.
If I run the following code:
phrase = "Don't Panic!"
phraseList = list(phrase)
print(phrase)
print(phraseList)
ontap = ['o', 'n', 't', 'a', 'p']
for letter in phraseList:
print("Letter ", letter)
#if letter not in ontap:
# phraseList.remove(letter)
print(phraseList)
I get the following expected output:
Don't Panic!
['D', 'o', 'n', "'", 't', ' ', 'P', 'a', 'n', 'i', 'c', '!']
Letter D
Letter o
Letter n
Letter '
Letter t
Letter
Letter P
Letter a
Letter n
Letter i
Letter c
Letter !
['D', 'o', 'n', "'", 't', ' ', 'P', 'a', 'n', 'i', 'c', '!']
However if I remove the comments I get this unexpected behaviour:
Don't Panic!
['D', 'o', 'n', "'", 't', ' ', 'P', 'a', 'n', 'i', 'c', '!']
Letter D
Letter n
Letter '
Letter
Letter a
Letter n
Letter i
Letter !
['o', 'n', 't', 'P', 'a', 'n', 'c']
So my question is, in the loop I would expect PRINT to be performed first before the list. remove function runs but it doesn't seem to work that way. Why? It seems to be skipping letters in the print like the letter C.
Also why does the compare seem to ignore the letter C when it clearly isn't in the ontap variable.
I am probably missing something extremely obvious. Does it have something to do with resizing the list and running a loop on it at the same time?
Thanks for any insight.
As the comments on the question confirm, the problem is indeed modifying phraseList while iterating over it. In a bit more detail, what's happening is this: when you go into the for loop, an iterator is created to iterate over phraseList. In the first iteration, the iterator supplies phraseList[0], which is D. This is not in the ontap list, so we do phraseList.remove('D'). On the next iteration, phraseList is now ['o', 'n', "'", 't', ...], but the iterator doesn't know it's changed - it just knows that now it needs to supply phraseList[1], which is now n. This is why the second iteration prints n, rather than o. c is never removed from phraseList because the only place it occurs is right after the first time i appears. When i is removed from phraseList, on the next loop, c is skipped. (Similarly, P is not removed because it's right after the first instance of <space>.)
The simplest way to fix your loop would be to iterate over a copy of phraseList:
for letter in list(phraseList):
print("Letter ", letter)
if letter not in ontap:
phraseList.remove(letter)
This way changing the original phraseList doesn't affect the iteration. You could also be more concise (and, in my opinion, more clear) with a list comprehension. The following accomplishes exactly what the for loop above does:
phraseList = [letter for letter in phraseList if letter in ontap]
I have one question:
If I have something like
['a', 'o', 'r', 'x', ' ', 's', 'n', ' ', 'k', 'p', 'l', 'q', 't']
How can I add for example 3 letters generated using random.choice() before and after every string in this list?
You should do the following:
generate a string containing all the letters
use ranodm.sample() instead of random.choice() to generate a list of 3 random letters, which you then should join()
return an in-place list with the new elements
It'd look like this:
import string
import random
def add_str(lst):
_letters = string.ascii_letters
return [''.join(random.sample(set(_letters), 3)) + letter + ''.join(random.sample(set(_letters), 3))
for letter in lst]
print(add_str(['a', 'o', 'r', 'x', ' ', 's', 'n', ' ', 'k', 'p', 'l', 'q', 't']))
> ['FUsaeNZ', 'pASoiTI', 'XfbrUXe', 'ZyKxhSs', 'lIJ blk', 'bJXseAI', 'uFcnUeQ', 'KRd wfF', 'VyPkjvq', 'CbwpCro', 'QOTlNfi', 'UNuqRDe', 'hEjtnIv']
I supposed you want different letters at the beginning and the end of each letter from the string. If you need them to be the same, you can handle it. Since you didn't provide any example, I answered your exact question and what I understood from it. If you need something else (and it looks like it's the case from the comments), you have where to start from anyway
I'm trying to create a Python function that receives a letter (a string with only one alphabetic character) and returns the 0-based numerical position of that letter in the alphabet. It should not be case-sensitive, and I can't use import.
So entering "a" should return
0
Entering "A" should also return
0
Entering "O" should return
14
And so on.
I had noticed this question but the top answer uses import and the second answer doesn't make any sense to me / doesn't work. I tried to apply the second answer like this:
letter = input("enter a letter")
def alphabet_position(letter):
return ord(letter) - 97
print((alphabet_position)(letter))
but I got a TypeError:
TypeError: ord() expected a character, but string of length 2 found
Just like the asker in the question that I linked, I'm also trying to send the characters "x" amount of steps back in the alphabet, but in order to do that I need to create this helper function first.
I'm thinking there must be a way to store the letters in two separate lists, one lower-case and one upper-case, and then see if the string that the user entered matches one of the items in that list? Then once we find the match, we return it's (0-based) numerical position?
letter = input("enter a letter")
def alphabet_position(letter):
position = 0
#letter_position = index value that matches input
lower_case_list ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
'y', 'z']
upper_case_list ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y','Z']
#if letter is in lower_case_list, return it's 0-based numerical position.
#else, if letter is in upper_case_list, return it's 0-based numerical position.
#else, print("Enter a valid letter")
return letter_position
Please help if you have any suggestions. Thank you.
It's probably simpler to just convert from uppercase or lowercase to specifically lowercase with the .lower() method, and use the built in list of letters (string.ascii_lowercase). You can find the index of a list's element by using the .index() method.
import string
letter = input('enter a letter: ')
def alphabet_position(letter):
letter = letter.lower()
return list(string.ascii_lowercase).index(letter)
print(alphabet_position(letter))
When you called alphabet_position, it is expecting an argument so you need to do func_name(arg) format.
Another way you could do this is to use dictionary comprehension to create a dict of letter-position pairs, like so:
from string import lowercase as l
alphabet_lookup = {letter:pos for letter,pos in zip(l, range(len(l)))}
and then
f = lambda letter: alphabet_lookup[letter.lower()]
is the desired function.
I suggest using a dictionary. It might be a large amount of code to do something relatively simple, but I find it easier to make sense of it this way (and if you are new to python it will help you learn). If you google python dictionaries you can learn lots more about them, but here is the basic concept:
Code for python version 3.X:
def alphabet_position(letter):
alphabet_pos = {'A':0, 'a':0, 'B':1, 'b':1}
pos = alphabet_pos[letter]
return pos
letter = input('Enter a letter: ')
print(alphabet_position(letter))
Code for python version 2.7:
def alphabet_position(letter):
alphabet_pos = {'A':0, 'a':0, 'B':1, 'b':1}
pos = alphabet_pos[letter]
return pos
letter = raw_input('Enter a letter: ')
print alphabet_position(letter)
If you run that, it will print 1 because it searches through the alpahbet_pos dictionary and finds the value that corresponds to the entry entitled 'B'. Notice that you can have multiple entries with the same value, so you can do uppercase and lowercase in the same dictionary. I only did letters A and B for the sake of time, so you can fill out the rest yourself ;)
I once had to enter every element on the periodic table and their corresponding atomic mass, and that took forever (felt much longer than it actually was).
I'm writing a function that needs to go through a list of lists, collect all letters uppercase or lowercase and then return a list with 1 of each letter that it found in order. If the letter appears multiple times in the list of lists the function only has to report the first time it sees the letter.
For example, if the list of lists was [['.', 'M', 'M', 'N', 'N'],['.', '.', '.', '.', 'g'], ['B', 'B', 'B', '.','g']] then the function output should return ["M","N","g","B"].
The code I have so far seems like it could work but it doesn't seem to be working. Any help is appreciated
def get_symbols(lot):
symbols = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
newlot = []
for i in lot:
if i == symbols:
newlot.append(symbols)
return newlot
else:
return None
To build on your existing code:
import string
def get_symbols(lot):
symbols = string.ascii_lowercase + string.ascii_uppercase
newlot = []
for sublot in lot:
for x in sublot:
if x in symbols and x not in newlot:
newlot.append(x)
return newlot
print get_symbols([['.', 'M', 'M', 'N', 'N'],['.', '.', '.', '.', 'g'], ['B', 'B', 'B', '.','g']])
Using string gets us the letters a little more neatly. We then loop over each list provided (each sublot of the lot), and then for each element (x), we check if it is both in our list of all letters and not in our list of found letters. If this is the case, we add it to our output.
There are a few things wrong with your code. You are using return in the wrong place, looping only over the outer list (not over the items in the sublists) and you were appending symbols to newlot instead of the matched item.
def get_symbols(lot):
symbols = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' # You should define this OUTSIDE of the function
newlot = []
for i in lot: # You are iterating over the outer list only here
if i == symbols: # == does not check if an item is in a list, use `in` here
newlot.append(symbols) # You are appending symbols which is the alphabet
return newlot # This will cause your function to exit as soon as the first iteration is over
else:
return None # No need for this
You can use a double for loop and use in to check if the character is in symbols and isn't already in newlot:
l = [['.', 'M', 'M', 'N', 'N'],['.', '.', '.', '.', 'g'], ['B', 'B', 'B', '.','g']]
symbols = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
def get_symbols(lot):
newlot = []
for sublist in lot:
for i in sublist:
if i in symbols and i not in newlot:
newlot.append(i)
return newlot
This is the output for your list:
>>> get_symbols(l)
['M', 'N', 'g', 'B']
this also can be done by using chain, OrderedDict and isalpha as follow
>>> from collections import OrderedDict
>>> from itertools import chain
>>> data = [['.', 'M', 'M', 'N', 'N'],['.', '.', '.', '.', 'g'], ['B', 'B', 'B', '.','g']]
>>> temp = OrderedDict.fromkeys(chain.from_iterable(data))
>>> [x for x in temp if x.isalpha()]
['M', 'N', 'g', 'B']
>>>
chain.from_iterable will serve the same purpose as if you concatenate all the sublist in one
As the order is relevant, OrderedDict will server the same purpose as an set by removing duplicates with the added bonus of preserving the order of the first instance of the object added. The fromkeys class-method will create a dictionary with the given keys and same value, which by default is None, and as we don't care about it, for our purpose is a orderer set
Finally the isalpha will tell you if the string is a letter or not
you can also take a look at the unique_everseen recipe, because itertools is your best friend I recommend to put all those recipes in a file that is always at hand, they always are helpful
I am doing a python project for my Intro to CSC class. We are given a .txt file that is basically 200,000 lines of single words. We have to read in the file line by line, and count how many times each letter in the alphabet appears as the first letter of a word. I have the count figured out and stored in a list. But now I need to print it in the format
"a:10,898 b:9,950 c:17,045 d:10,596 e:8,735
f:11,257 .... "
Another aspect is that it has to print 5 of the letter counts per line, as I did above.
This is what I am working with so far...
def main():
file_name = open('dictionary.txt', 'r').readlines()
counter = 0
totals = [0]*26
alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
for i in file_name:
for n in range(0,26):
if i.startswith(alphabet[n]):
totals[n] = totals[n]+1
print(totals)
main()
This code currently outputs
[10898, 9950, 17045, 10675, 7421, 7138, 5998, 6619, 6619, 7128, 1505, 1948, 5393, 10264, 4688, 6079, 15418, 890, 10790, 20542, 9463, 5615, 2924, 3911, 142, 658]
I would highly recommend using a dictionary to store the counts. It will greatly simplify your code, and make it much faster. I'll leave that as an exercise for you since this is clearly homework. (other hint: Counter is even better). In addition, right now your code is only correct for lowercase letters, not uppercase ones. You need to add additional logic to either treat uppercase letters as lowercase ones, or treat them independently. Right now you just ignore them.
Having said that, the following will get it done for your current format:
print(', '.join('{}:{}'.format(letter, count) for letter, count in zip(alphabet, total)))
zip takes n lists and generates a new list of tuples with n elements, with each element coming from one of the input lists. join concatenates a list of strings together using the supplied separator. And format does string interpolation to fill in values in a string with the provided ones using format specifiers.
python 3.4
the solution is to read the line of the file into words variable below in cycle and use Counter
from collections import Counter
import string
words = 'this is a test of functionality'
result = Counter(map(lambda x: x[0], words.split(' ')))
words = 'and this is also very cool'
result = result + Counter(map(lambda x: x[0], words.split(' ')))
counters = ['{letter}:{value}'.format(letter=x, value=result.get(x, 0)) for x in string.ascii_lowercase]
if you print counters:
['a:3', 'b:0', 'c:1', 'd:0', 'e:0', 'f:1', 'g:0', 'h:0', 'i:2', 'j:0', 'k:0', 'l:0', 'm:0', 'n:0', 'o:1', 'p:0', 'q:0', 'r:0', 's:0', 't:3', 'u:0', 'v:1', 'w:0', 'x:0', 'y:0', 'z:0']