Conditional Statement produces unintended output - python

I am currently experimenting with lists in python and am trying to create a program that will simulate a name game (click here for reference).
The program asks for user's input and generates a list with each letter of the user's name. It then has to generate 3 new names, each beginning with "b", "f", "m".
So Robert would become:
[['b', 'o', 'b', 'e', 'r', 't'], ['f', 'o', 'b', 'e', 'r', 't'],
['m', 'o', 'b', 'e', 'r', 't']]
However, in cases where the name begins with the same letter, the first letter is simply removed, so Billy would become
[['i', 'l', 'l', 'y'], ['f', 'i', 'l', 'l', 'y'], ['m', 'i', 'l',
'l', 'y']]
However, when I run my code instead the output is:
[['b', 'i', 'l', 'l', 'y'], ['f', 'i', 'l', 'l', 'y'], ['m', 'i',
'l', 'l', 'y']]
Can anyone help? Is there an error in my conditional? Heres my code:
# Asks for user name
user_name = input("Enter name here: ")
name = list(user_name)
# Create an empty list that will contain a subsets of lists.
master_list = []
# List containing the first letter of each new name
beginning_of_word = ["b", "f", "m"]
# Creates 3 new names and appends them to master_list
for var in beginning_of_word:
new_list = list(name)
# if new_list[0] != 'B' or new_list[0] != 'F' or new_list[0] != 'M':
if 'B' not in new_list or 'F' not in new_list or 'M' not in new_list:
new_list.pop(0)
new_list.insert(0, var)
master_list.append(new_list)
else:
new_list.pop(0)
master_list.append(new_list)
print(master_list)

I have made a small correction in your condition statement. In your original program, the else block was getting skipped. In this approach, we first check for the values that are to be removed and then perform replacement in else block of the code. Secondly, the program is case sensitive. You have your characters in Uppercase in condition statement but in your lists, they are lowercase. In the approach below they are all lowercase. If you want it to be robust, you can add or or convert the input to lowercase before doing any operation.
user_name = input("Enter name here: ")
name = list(user_name)
# Create an empty list that will contain a subsets of lists.
master_list = []
# List containing the first letter of each new name
beginning_of_word = ["b", "f", "m"]
# Creates 3 new names and appends them to master_list
for var in beginning_of_word:
new_list = list(name)
if (("b" in new_list) or ("f" in new_list) or ("m" in new_list)):
new_list.pop(0)
#new_list.insert(0,)
master_list.append(new_list)
else:
new_list.pop(0)
new_list.insert(0,var)
master_list.append(new_list)
print(master_list)
The output is
Enter name here: john
[['b', 'o', 'h', 'n'], ['f', 'o', 'h', 'n'], ['m', 'o', 'h', 'n']]
Enter name here: billy
[['i', 'l', 'l', 'y'], ['i', 'l', 'l', 'y'], ['i', 'l', 'l', 'y']]

Related

How can I reference a string (e.g. 'A') to the index of a larger list (e.g. ['A', 'B', 'C', 'D', ...])?

I have been racking my brain and scouring the internet for some hours now, please help.
Effectively I am trying to create a self-contained function (in python) for producing a caesar cipher. I have a list - 'cache' - of all letters A-Z.
def caesarcipher(text, s):
global rawmessage #imports a string input - the 'raw message' which is to be encrypted.
result = ''
cache = ['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']
Is it possible to analyze the string input (the 'rawmessage') and attribute each letter to its subsequent index position in the list 'cache'? e.g. if the input was 'AAA' then the console would recognise it as [0,0,0] in the list 'cache'. Or if the input was 'ABC' then the console would recognise it as [0,1,2] in the list 'cache'.
Thank you to anyone who makes the effort to help me out here.
Use a list comprehension:
positions = [cache.index(letter) for letter in rawmessage if letter in cache]
You can with a list comprehension. Also you can get the letter from string.
import string
print([string.ascii_uppercase.index(c) for c in "AAA"])
# [0, 0, 0]
print([string.ascii_uppercase.index(c) for c in "ABC"])
# [0, 1, 2]
result = []
for i in list(rawmessage):
result.append(cache.index(i))

How to make dictionary of alphabet and scrambled alphabet?

I need to create multiple dictionaries for another program using the alphabet as the key and a scrambled alphabet (the first one I have to do is BDFHJLCPRTXVZNYEIWGAKMUSQO) as the value. This is what I have so far but it says "unhashable type: 'list'"
_list = input("Enter list: ")
alpha = ['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']
dict1 = {}
for i in range(0,len(_list)):
dict1[alpha][i] == _list[i]
print(dict1)
There are two errors in your code.
dict1[alpha][i] should be dict1[alpha[i]]
As pointed out by Paul Rooney, you cannot use a list as a dictionary key, but I don't think that is what you are trying to do. Instead, you just want the ith element of the list alpha.
the == should be =.
== is used to compare, = is used to assign a value.
Also, the pythonic way to do your iteration is as follows:
dict1 = {alpha[idx]: character for idx, character in enumerate(_list)}
which is the equivalent of
dict1 = {}
for idx, character in enumerate(_list):
dict1[alpha[idx]] = character

Remove words from list containing certain characters

I have a long list of words that I'm trying to go through and if the word contains a specific character remove it. However, the solution I thought would work doesn't and doesn't remove any words
l3 = ['b', 'd', 'e', 'f', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y']
firstcheck = ['poach', 'omnificent', 'aminoxylol', 'teetotaller', 'kyathos', 'toxaemic', 'herohead', 'desole', 'nincompoophood', 'dinamode']
validwords = []
for i in l3:
for x in firstchect:
if i not in x:
validwords.append(x)
continue
else:
break
If a word from firstcheck has a character from l3 I want it removed or not added to this other list. I tried it both ways. Can anyone offer insight on what could be going wrong? I'm pretty sure I could use some list comprehension but I'm not very good at that.
The accepted answer makes use of np.sum which means importing a huge numerical library to perform a simple task that the Python kernel can easily do by itself:
validwords = [w for w in firstcheck if all(c not in w for c in l3)]
you can use a list comprehension:
import numpy as np
[w for w in firstcheck if np.sum([c in w for c in l3])==0]
It seems all the words contain at least 1 char from l3 and the output of above is an empty list.
If firstcheck is defined as below:
firstcheck = ['a', 'z', 'poach', 'omnificent']
The code should output:
['a', 'z']
If you want to avoid all loops etc, you can use re directly.
import re
l3 = ['b', 'd', 'e', 'f', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y']
firstcheck = ['azz', 'poach', 'omnificent', 'aminoxylol', 'teetotaller', 'kyathos', 'toxaemic', 'herohead', 'desole', 'nincompoophood', 'dinamode']
# Create a regex string to remove.
strings_to_remove = "[{}]".format("".join(l3))
validwords = [x for x in firstcheck if re.sub(strings_to_remove, '', x) == x]
print(validwords)
Output:
['azz']
Ah, there was some mistake in code, rest was fine:
l3 = ['b', 'd', 'e', 'f', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y']
firstcheck = ['aza', 'ca', 'poach', 'omnificent', 'aminoxylol', 'teetotaller', 'kyathos', 'toxaemic', 'herohead', 'desole', 'nincompoophood', 'dinamode']
validwords = []
flag=1
for x in firstcheck:
for i in l3:
if i not in x:
flag=1
else:
flag=0
break
if(flag==1):
validwords.append(x)
print(validwords)
So, here the first mistake was, the for loops, we need to iterate through words first then, through l3, to avoid the readdition of elements.
Next, firstcheck spelling was wrong in 'for x in firstcheck` due to which error was there.
Also, I added a flag, such that if flag value is 1 it will add the element in validwords.
To, check I added new elements as 'aza' and 'ca', due to which, now it shows correct o/p as 'aza' and 'ca'.
Hope this helps you.

How to print a list from user input sentence?

So I am supposed to make a script that asks user to make a sentence then discard all characters but lower case and print the lower case letters like this ['m', 'y', 'p', 'a', 's', 's', 'w', 'o', 'r', 'd'].
My script:
#!/usr/bin/python3
sentence = input("Enter a sentence: ")
for letter in sentence:
if letter.islower():
print(letter)
and this is the output:
o
e
s
h
i
s
w
r
k
Seems like you want to produce a list, you have list comprehensions to make life easy:
l = ['P', 'm', 'y', 'H', 'p', 'a', 's', 's', 'w', 'o', 'r', 'd']
out = [i for i in l if i.islower()]
print(out)
# ['m', 'y', 'p', 'a', 's', 's', 'w', 'o', 'r', 'd']
Which is equivalent to:
out = []
for i in l:
if i.islower():
out.append(i)
print(out)
# ['m', 'y', 'p', 'a', 's', 's', 'w', 'o', 'r', 'd']
You might be looking for end = ",":
sentence = input("Enter a sentence: ")
for letter in sentence:
if letter.islower():
print(letter, end=",")
# ^^^
Your program is almost OK, only instead of printing every lowercase character, append it to a list, and finally print only that list:
sentence = input("Enter a sentence: ")
lowercases = [] # prepare an empty list
for letter in sentence:
if letter.islower():
lowercases.append(letter)
print(lowercases) # print the filled list
Test:
Enter a sentence: The End of Universe.
['h', 'e', 'n', 'd', 'o', 'f', 'n', 'i', 'v', 'e', 'r', 's', 'e']

Appending lists to new list in for loop [duplicate]

This question already has answers here:
How do I clone a list so that it doesn't change unexpectedly after assignment?
(24 answers)
Closed 3 years ago.
I am currently experimenting with lists in python and am trying to create a program that will simulate the name game (click here for refrence).
The program asks for user input and generates a list with each letter of the user's name. However, it then has to generate 3 new names, each beginning with "b", "f", "m". This is where I run into a problem. When appending to master_list, and later printing my result I get the output:
[['m', 'o', 'b', 'e', 'r', 't'], ['m', 'o', 'b', 'e', 'r', 't'],
['m', 'o', 'b', 'e', 'r', 't']]
When user input = "Robert"
Heres my code:
# Asks for user name
user_name = input("Enter name here: ")
name = list(user_name)
# Create an empty list that will contain a subsets of lists.
master_list = []
# List containing the first letter of each new name
beginning_of_word = ["b", "f", "m"]
# Creates 3 new names and appends them to master_list
for var in beginning_of_word:
new_list = name
new_list.pop(0)
new_list.insert(0, var)
print(new_list)
master_list.append(new_list)
if new_list != name:
new_list = name
The intended output when master_list is printed should be:
[['b', 'o', 'b', 'e', 'r', 't'], ['f', 'o', 'b', 'e', 'r', 't'],
['m', 'o', 'b', 'e', 'r', 't']]
Does anyone have ideas as to why this is happening?
Although you named your variable new_list, the fact is you were operating on the same old list each time. To modify a list, and retain the original, you need to copy the list:
# Asks for user name
user_name = input("Enter name here: ")
name = list(user_name)
# Create an empty list that will contain a subsets of lists.
master_list = []
# List containing the first letter of each new name
beginning_of_word = ["b", "f", "m"]
# Creates 3 new names and appends them to master_list
for var in beginning_of_word:
new_list = list(name) # a copy of 'name'
new_list[0] = var
master_list.append(new_list)
print(master_list)
OUTPUT
% python3 test.py
Enter name here: Robert
[['b', 'o', 'b', 'e', 'r', 't'], ['f', 'o', 'b', 'e', 'r', 't'], ['m', 'o', 'b', 'e', 'r', 't']]
%

Categories