I have the following program which seeks to check the similarity between two lists. However, the originalword (list) prints correctly the first time but not the second therefore the code doesn't work to check equivalence.
https://trinket.io/python3/b3b7827717
Can anyone spot the error? If so, could a solution be posted
a) using lists
b) Not introducing any new skills (e.g. string slicing)
def palindromechecker():
print("----Palindrome Checker---")
word=input("Enter word:")
#empty list for reversed word
originalword=[]
reversedword=[]
#put each letter in word in the list originallist
for i in range(len(word)):
originalword.append(word[i])
print("Print original word in order:",originalword)
#reverse the word
for i in range(len(word)):
reversedword.append(originalword.pop())
print("Reversed word:",reversedword)
print("Original word:",originalword)
#are original word and reversed word the same?
if originalword==reversedword:
print("--Palindrome Found--")
else:
print("--Not a Palindrome---")
palindromechecker()
You make originalword list empty by doing that originalword.pop() in the second loop. Better way to do that is just reverse list like that
reversedword = originalword[::-1]
It will work without loop
Or you can do something like that:
for i in range(len(word)):
reversedword.append(originalword[-1-i])
If you use .pop() method, it will update the existing list by removing the last element from the list. So it is exhausting your originalword list.
I read that you don't want to use string[::-1]. Here is a similar but not the same workaround. You have to run the loop in reverse.
#reverse the word
for i in range(len(word)-1, -1, -1):
reversedword.append(originalword[i])
Related
How do I convert single item in a list by using for loop?
I want program to recognize plane not being in lowercase and making it lowercase.
vehicles = ['car', 'bicycle', 'Plane',]
for vehicle in vehicles:
if vehicle == vehicle.lower():
print(f"{vehicle.title()} is in lowercase")
else:
print(f"Vehicle is not in lowercase: {vehicle}")
I tried with:
if vehicle in vehicles != vehicle.lower():
vehicle = vehicle.lower()
print(vehicles)
But when I print list again, it still shows plane with first capital letter.
Edit: Sorry for some confusion, I added "print(f"{vehicle.title()} is in lowercase")" just for esthetics. What I want, is to make program recognize string not being in lowercase and then modify that string in a list, then when list in being printed again, it shows "Plane" in list as "plane".
Your first bit of code correctly detects whether a string is not lowercased, but you print the non-lowercased version (using vehicle.title()). You don't actually need to detect whether it's lowercase or not. Just lowercase them all --- it's cheap enough.
vehicles = [vehicle.lower() for vehicle in vehicles]
It sounds like you simply to make everything lowercase in that case you could use list comprehension:
vehicles_lower = [v.lower() for v in vehicles]
print(vehicles_lower)
Your question is a duplicate of
Change value of currently iterated element in list
You have to change your for loop like this if you want to change the list:
a_list = ["a", "b", "c"]
for i in range(len(a_list)):
a_list[i] = a_list[i] + a_list[i]
print(a_list)
In his answer, #erip provided yet another syntax to do it by assigning the result back to the list.
The question is this:
Given an array of strings, remove each string that is an anagram of an earlier string, then return the remaining array in sorted order.
Example
str = ['code', 'doce', 'ecod', 'framer', 'frame']
code and doce are anagrams. Remove doce from the array and keep the first occurrence code in the array.
code and ecod are anagrams. Remove ecod from the array and keep the first occurrence code in the array.
code and framer are not anagrams. Keep both strings in the array.
framer and frame are not anagrams due to the extra r in framer. Keep both strings in the array.
Order the remaining strings in ascending order: ['code','frame','framer'].
The solution code is:
def checkForAnagrams(word, arr):
# Checking if the word has an anagram in the sliced array.
for x in arr:
if (sorted(word) == sorted(x)):
return True
return False
def funWithAnagrams(text):
limit = len(text)
text.reverse()
# Creating a copy of the list which will be modified,
# and will not affect the array slicing during the loop.
final_text = list(text)
# Looping through the list in reverse since we're eliminating
# the second anagram we find from the original list order.
count = 0
for i in range(0, limit):
if text[i+1:] and checkForAnagrams(text[i], text[i+1:]):
final_text.pop(i - count)
count += 1
return sorted(final_text)
I want to understand in the function funwithanagrams, how is the text[i+1:] useful?
if checkForAnagrams(text[i], text[i+1:]):
would have achieved the same output.
PS-This is not my code. I found it online and really want to know how the text[i+1:] will impact the output if removed?
The if text[i+1:] checks whether the sliced list is empty or not. If it wasn't there, in the final iteration of the for loop, an error would've occurred when iterating through text[i+1:] as it would be empty. The if text[i+1:] equates to False in the last iteration due to which checkForAnagrams(text[i], text[i+1:]) never executes and no error occurs.
A better way to write this code would be to remove the if text[i+1:] and instead replace range(0, limit) with range(0, limit-1) so that text[i+1:] is never empty (will have one element in the last iteration of the for loop). This method would reduce the number of checks required and make the code more efficient (doesn't make a noticeable difference for a code this small).
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
Im a beginner to your world. I have seen many attempts to answer this question using fancy builtin function and have found the answer on how to do this a thousand times but NONE using two for loops method.
I would like for the code to only reverse a vowel when it finds one in a string, using the two for loop method.
I coded something that didnt seem to work and I dont quite understand why,
for x in newWord:
for y in vowels:
if x == y:
newWord[x] = newWord[7]
print newWord
with vowels being a list of vowels, with newWord also being a list.
This code is currently not working, like most others who have tried the two for loop method. Any help is appreciated. Thanks
Roughly the approach you want to use is to make two passes over the list of characters. In the first pass you find the index of each vowel, building a list of work to be done (locations of vowels to be swapped).
Then you prepare your work list by matching the first and last items until you have less than two items left in the work list. (An odd number of vowels means that the one in the middle doesn't have to be swapped with anything).
Now you simply iterate over the work list, tuples/pairs of indexes. Swap the character at the first offset with the character at the other one for each pair. Done.
(This is assuming you want transform the list in place. If not then you can either just start with a copy: new_word = word[:] or can iterate over enumerate(word) and conditionally either append the character at each point (if the offset isn't in your work list) ... or append the offset character (if this index matches one of those in your list). I the latter case you might make your work list a dictionary instead).
Here's the code to demonstrate:
def rev_vowels(word):
word = list(word)
results = word[:]
vowel_locations = [index for index, char in enumerate(word) if char in 'aeiou']
work = zip(vowel_locations[:int(len(vowel_locations)/2)], reversed(vowel_locations))
for left, right in work:
results[left], results[right] = word[right], word[left]
return results
This does use a list comprehension, the zip() and reversed() builtins, a complex slice for the first argument to zip(), and the Python tuple packing idiom for swapping variables. So you might have to replace those with more verbose constructs to fulfill your "no fancy builtins" constraint.
Fundamentally, however, a list comprehension is just syntactic sugar around a for loop. So, overall, this demonstrates the approach using two for loops over the data. While I'm returning a copy of the data as my results the code would work without that. (That's why I'm using the tuple packing idiom on line seven (just before the return statement).
If this question is being asked in an interview context I'm reasonably confident that this would be a reasonably good answer. You can easily break down how to implement zip, how to expand a list comprehension into a traditional for suite (block), and the swap line could be two separate assignments when returning a copy rather than performing an in-place transformation on the data.
These variable names are very verbose. But that's to make the intentions especially clear.
This code should solve your problem without using any "fancy builtin functions".
def f(word):
vowels = "aeiou"
string = list(word)
i = 0
j = len(word)-1
while i < j:
if string[i].lower() not in vowels:
i += 1
elif string[j].lower() not in vowels:
j -= 1
else:
string[i], string[j] = string[j], string[i]
i += 1
j -= 1
return "".join(string)
I have a list of URLs in an open CSV which I have ordered alphabetically, and now I would like to iterate through the list and check for duplicate URLs. In a second step, the duplicate should then be removed from the list, but I am currently stuck on the checking part which I have tried to solve with a nested for-loop as follows:
for i in short_urls:
first_url = i
for s in short_urls:
second_url = s
if i == s:
print "duplicate"
else:
print "all good"
The print statements will obviously be replaced once the nested for-loop is working. Currently, the list contains a few duplicates, but my nested loop does not seem to work correctly as it does not recognise any of the duplicates.
My question is: are there better ways to do perform this exercise, and what is the problem with the current nested for-loop?
Many thanks :)
By construction, your method is faulty, even if you indent the if/else block correctly. For instance, imagine if you had [1, 2, 3] as short_urls for the sake of argument. The outer for loop will pick out 1 to compare to the list against. It will think it's finding a duplicate when in the inner for loop it encounters the first element, a 1 as well. Essentially, every element will be tagged as a duplicate and if you plan on removing duplicates, you'll end up with an empty list.
The better solution is to call set(short_urls) to get a set of your urls with the duplicates removed. If you want a list (as opposed to a set) of urls with the duplicates removed, you can convert the set back into a list with list(set(short_urls)).
In other words:
short_urls = ['google.com', 'twitter.com', 'google.com']
duplicates_removed_list = list(set(short_urls))
print duplicates_removed_list # Prints ['google.com', 'twitter.com']
if i == s:
is not inside the second for loop. You missed an indentation
for i in short_urls:
first_url = i
for s in short_urls:
second_url = s
if i == s:
print "duplicate"
else:
print "all good"
EDIT: Also you are comparing every element of an array with every element of the same array. This means compare the element at position 0 with the element at postion 0, which is obviously the same.
What you need to do is starting the second for at the position after that reached in the first for.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
How to find positions of the list maximum?
A question from homework:
Define a function censor(words,nasty) that takes a list of words, and
replaces all the words appearing in nasty with the word CENSORED, and
returns the censored list of words.
>>> censor([’it’,’is’,’raining’], [’raining’])
[’it’,’is’,’CENSORED’]
I see solution like this:
find an index of nasty
replace words matching that index
with "CENSORED"
but i get stuck on finding the index..
You can find the index of any element of a list by using the .index method.
>>> l=['a','b','c']
>>> l.index('b')
1
Actually you don't have to operate with indexes here. Just iterate over words list and check if the word is listed in nasty. If it is append 'CENSORED' to the result list, else append the word itself.
Or you can involve list comprehension and conditional expression to get more elegant version:
Your approach might work, but it’s unnecessarily complicated.
Python allows a very simple syntax to check whether something is contained in a list:
censor = [ 'bugger', 'nickle' ]
word = 'bugger'
if word in censor: print 'CENSORED'
With that approach, simply walk over your list of words and test for each words whether it’s in the censor list.
To walk over your list of words, you can use the for loop. Since you might need to modify the current word, use an index, like so:
for index in len(words)):
print index, words[index]
Now all you need to do is put the two code fragments together.
You could use the handy built-in enumerate() function to step through the items in the list. For example:
def censor(words, nasty):
for i,word in enumerate(words):
if word...