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']]
%
Related
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))
This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 3 years ago.
I am using jupyter ide and I am getting different results for print(word) and appending to lst.
word = ["M","A","R","I","N","E"]
goal = ["A","I","R","M","E","N"]
lst = []
def search(ind_a,a,b,word):
for x in range(len(word)):
if word[x] == b:
temp=b
word[x]=word[ind_a]
word[ind_a]=temp
return word
def sequence(word,goal):
for ind_x,x,y in zip(range(len(word)),word,goal):
if(x==y):
continue
word=search(ind_x,x,y,word)
print(word)
lst.append(word)
return lst
when I called sequence(word,goal),I get succeding out:
sequence(word,goal)
Output:
['A', 'M', 'R', 'I', 'N', 'E']#print word statement
['A', 'I', 'R', 'M', 'N', 'E']
['A', 'I', 'R', 'M', 'E', 'N']
Out[193]:
[['A', 'I', 'R', 'M', 'E', 'N'],#return statement
['A', 'I', 'R', 'M', 'E', 'N'],
['A', 'I', 'R', 'M', 'E', 'N']]
where am ı wrong?
The problem is that lists hold pointers to objects that exist elsewhere in memory. That may sound complicated, so check this out:
a = [1, 2, 3]
b = a
b[0] = 5
print(a)
>>> [1, 5, 3]
What happened is that you didn't change b, you changed the list both a and b refer to!
So in your example, word is appended 3 times, but the list still "follows" the variable word. Instead try this:
from copy import copy
....
lst.append(copy(word))
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']]
This question already has answers here:
How do I clone a list so that it doesn't change unexpectedly after assignment?
(24 answers)
Closed 5 years ago.
list= []
x = ['A', 'B', 'C', 'D', 'E', 'F', 'G']
for i in range(2):
list.append(x)
list[0][0]="x"
print list
And after printing I get this:
[['x', 'B', 'C', 'D', 'E', 'F', 'G'], ['x', 'B', 'C', 'D', 'E', 'F', 'G']]
The first item in every list was replaced by 'x' whereas I only wanted the first item in the first list to be replaced by 'x'(hence the line list[0][0]="x")
The line list.append(x) adds a reference to x into list. Both sublists end up pointing to the same object (as does x). In fact, doing x[0] = 'x' would have the exact same effect as list[0][0] = 'x'. To make the sub-lists independent, make a copy by doing list.append(x.copy()) or list.append(x[:])
correctAnswers = ['A','C','A','A','D','B','C','A','C','B','A','D','C','A','D','C','B','B','D','A']
studentAnswers = []
correctList = []
file = open('forchapter7.txt','r')
student = file.readline()
student = student.rstrip('\n')
studentAnswers.append(student)
while student != '':
student = file.readline()
student = student.rstrip('\n')
studentAnswers.append(student)
print(studentAnswers)
print(correctAnswers)
file.close()
#displays this
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', '']
['A', 'C', 'A', 'A', 'D', 'B', 'C', 'A', 'C', 'B', 'A', 'D', 'C', 'A', 'D', 'C', 'B', 'B', 'D', 'A']
my text file is a plain .txt file with the letters A-T going down and no space or new line after T, why is my loop writing the blank space?
When you read your final line, student == 'T', so the loop repeats itself. When you try to file.readline() after you have finished reading the entire file, it returns '' because there is nothing else to read. You are then adding this to your list.
Just add a check for empty string before adding to the list:
if student:
studentAnswers.append(student)
EDIT:
An alternative you could use is to read all the lines with file.readlines() and iterate over the list. This will not run the loop an extra time:
for student in file.readlines():
studentAnswers.append(student.rstrip('\n')
You can even use list comprehension this way:
studentAnswers = [student.rstrip('\n') for student in file.readlines()]
Note, however, that if the file does have an empty line these last two methods will need checks to prevent them from adding an empty entry to the list.