Let's say I have this array:
arr = ["foo","bar","hey"]
I can print the "foo" string with this code :
for word in arr:
if word == "foo":
print word
But I want also check the next word if it equals to "bar" then it should print "foobar"
How can I check the next element in a for loop?
The items in a list can be referred to by their index. Using the enumerate() method to receive an iterator along with each list element (preferable to the C pattern of instantiating and incrementing your own), you can do so like this:
arr = ["foo","bar","hey"]
for i, word in enumerate(arr):
if word == "foo" and arr[i+1] == 'bar':
print word
However, when you get to the end of the list, you will encounter an IndexError that needs to be handled, or you can get the length (len()) of the list first and ensure i < max.
for i in range(len(arr)):
if arr[i] == "foo":
if arr[i+1] == 'bar':
print arr[i] + arr[i+1]
else:
print arr[i]
Rather than check for the next value, track the previous:
last = None
for word in arr:
if word == "foo":
print word
if last == 'foo' and word == 'bar':
print 'foobar'
last = word
Tracking what you already passed is easier than peeking ahead.
You can also do it with zip:
for cur, next in zip(arr, arr[1:]):
if nxt=='bar':
print cur+nxt
But keep in mind that the number of iterations will be only two since len(ar[1:]) will be 2
Related
I'm aware that I can use the .count() function for this, but I tried to do this with a for loop and I keep getting a compile error in line 6. Does anyone see what's wrong with this code and why it wouldn't give the same output? Thanks in advance!
def count_hi(string):
# Create an empty list to add to
num_hi = []
# for every index in string , if the character is h and the next is i,
# add element to list
for index in string:
if string[index] == 'h' AND string[index + 1] == 'i':
num_hi.append('hi found')
return len(num_hi) # return length of list
Why not use count?
def count_hi(string):
return string.count('hi')
Fix for your code:
def count_hi(string):
count = 0
for i in range(1, len(string)):
if string[i - 1] == 'h' and string[i] == 'i':
count += 1
return count
Python is case sensitive, not AND but and.
Appending to list and counting it is a lot of overhead, you should just use a variable and increment it every time you find hi.
Instead of enumerate, you can use range to start from index 1 and check your string from i - 1 and 1. Avoids another check.
I'd prefer the previous solution using .count(). Why to write code when there is a built-in method for you?
See Harshal Parekh's Asnwer, it provides a better analysis and explanation.
When you iterate over a string, you're not iterating over indexes, but over the letters themselves. A quick fix for this could be:
def count_hi(string):
num_hi = []
# for every index in string , if the character is h and the next is i, add element to list
for index, _character in enumerate(string):
if index == len(string) - 1:
break # on the last one, you'd get an index error.
if string[index] == 'h' and string[index + 1] == 'i': # "and", not "AND"
num_hi.append('hi found')
return len(num_hi) # return length of list
The simplest way to do this is to use the builtin collection module.
from collections import Counter
def count_hi(string):
counts = Counter(string.split())
return print(counts['hi'])
You can try this, it should do the trick.
def count_hi(str):
counter = 0
str.lower()
str.replace(' ', '')
for i in range(0, len(str)-1):
if str[i] == 'h' and str[i+1] == 'i':
counter += 1
return counter
My solution:
def count_hi(str):
sum = 0
for i in range(len(str)-1):
if str[i:(i+2)] == "hi":
sum += 1
return sum
Here I want to remove any vowels which repeat consecutively. But it shows error as "list out of index".
So I tried break if last element in list is reached, but still won't work.
Here is the code I tried:-
a=[]
b=str(input("enter the string"))
a=b.split(',')
c=['a','e','i','o','u']
for i in c:
for j in range(0,len(a)):
if (a[j+1] == a[len(a)]) is True:
break;
elif ((a[j] == a[j+1]) & (a[j+1] == i)) is True:
del[j]
e.join(a)
print(e)
Please show me how to solve this problem, or any other problem if in there.
How about maintaining a stack for consecutive vowels? whenever you see non-vowel string re-initialize the stack list and when you see vowels but are not consecutive you just add to the final list
stack=[]
new_list=[]
vowel=['a','i','o','u','e']
for i in your_string: # replace your string with actual string
if i not in vowel:
if len(stack) == 1:
new_list.append(stack[0])
new_list.append(i)
stack = []
else:
stack.append(i)
if len(stack) == 1:
new_list.append(stack[0])
You get a list out of index error because you are indexing at a value not in a
if (a[j+1] == a[len(a)]) is True:
a[len(a)] does not exist, arrays are zero indexed so they start from 0. An array with 5 items has index 0,1,2,3,4
the line should be:
if (a[j+1] == a[len(a) - 1]) is True:
Also 'is True' is redundant, so further refined:
if a[j+1] == a[len(a) - 1]:
Also is del[j] an error? should it be del a[j]?
If this is the case, the program will run into further errors as you are iterating over the entire Original size of the array but deleting values during this iteration, so it will look for items that no longer exist.
First detail is this: if (a[j+1] == a[len(a)]) is True: from what I understood this is to break the code when it is necessary. But that is completely unnecessary. Instead you should fix the number of iterations in the beginning, which should be for j in range(0,len(a)-1):
Another problem is that you aren't really iterating through the letters, just each comma separated phrases. If you put "Hello, World" you aren't checking the letters, you check "Hello" and " World". You might as well remove b and let a just be the raw input.
Since a would then be a string, to erase the i-th letter of a string you can use the function below.
def remove_jth(word, j):
word = word[:j] + word[j+1:]
Finally since you are using range, it will build a "list" that has the size len(a) when you start the for, but as you remove vowels, the length of a gets shorter and the range you had at the beginning will be to much. If you fix all of these things you should have it right
You can do it this way:
a=[]
b=str("a,a,a,b,e,e,e,c,x,d")
a=b.split(',')
c=['a','e','i','o','u']
j = 0
for i in c:
while j < len(a)-1:
if a[j] == a[j+1] and a[j] == i:
del a[j]
else:
j = j+1
j=0
Use a while loop to check through the list and delete consecutive duplicates. Then reset the the while loop back to zero and run through the list again.
Using a for loop will not work,if you are deleting items in the list that is being used to iterate over.
b=str("a,a,a,b,e,e,e,c,x,d") was just used to test the code.
To print the results you can just do print(a) it will print the list out.
I used this Stack Overflow post as reference.
I edited it to suit you:
result=original.replace('a','').replace('e',''),replace('i','').replace('o','').replace('u','')
original is your input string and result is your output string.
t=input()
st=""
vow=['a','e','i','o','u']
st+=t[0]
for i in range(1,len(t)):
if(t[i].lower() in vow):
if(t[i-1].lower() not in vow and i-1>=0):
st+=t[i]
else:
st+=t[i]
print(st)
I'm trying to make a function that takes in a string from a user and then outputs the same string. However for each letter in an even position it outputs the corresponding lower case letter, and for each letter in an odd position it outputs the corresponding uppercase letter. Keep in mind only one word will be passed through it at a time.
I've tried to create a for loop with an if statement nested within it, but so far, the for loop stops after iterating through the first letter. My code is below:
def converter(string):
for letters in string:
if len(letters) % 2 == 0:
return letters.lower()
elif len(letters)% 2 != 0:
return letters.upper()
When I run the code:
converter('app')
The output I get is 'A'
The expected output should be 'aPp'
The first thing you need to know is that in Python, strings are immutable. So "modifying" a string means you have to build a new string from scratch in (here, I call that newstring).
Second, you are misunderstanding the loop. You are saying for letters in string. This loop iterates over each letter of the string. On the first iteration, letters is the first letter of the strong. You then convert it to upper case (since the length of a single letter is always 1), and return it. You aren't reaching the rest of the letters! In the code below, I change the plurality to just letter to make this idea clear.
This amends all of those problems:
def converter(string):
newstring = ""
for i, letter in enumerate(string):
if i % 2 == 0:
newstring += letter.lower()
elif i % 2 != 0:
newstring += letter.upper()
return newstring
This can be boiled down to a nice list comprehension:
def converter(string):
return "".join([letter.lower() if i % 2 == 0 else letter.upper()
for i, letter in enumerate(string)])
In [1]: def converter(string):
...: return ''.join([j.upper() if i % 2 == 1 else j.lower() for i, j in enumerate(string)])
In [2]: converter('apple')
Out[2]: 'aPpLe'
''.join([s.lower() if c % 2 == 0 else s.upper() for c, s in enumerate('apple')])
# returns 'aPpLe'
first check for the condition, then iterate through the string using the nice old enumerate built-in.
Two versions, return opposite answers, but always one comes out wrong. I'm not sure where I've gone wrong. I've tried a series of other options, but this seems to get the closest. EDIT: Needs to be in a loop
goals: identify element in list, identify when element is not in list, identify when list is [], return strings accordingly.
def search_for_string(a_list, search_term):
i=0
for search_term in a_list:
i += 1
if a_list[i] == search_term:
return 'string found!'
elif a_list[i] != search_term:
return 'string not found2'
if len(a_list) == 0:
return 'string not found'
apple = search_for_string(['a', 'b', 'c'], 'd')
print(apple)
def search_for_string(a_list, search_term):
i=0
for search_term in a_list:
if a_list[i] == search_term:
return 'string found!'
elif a_list[i] != search_term:
return 'string not found2'
i += 1
if len(a_list) == 0:
return 'string not found'
apple = search_for_string(['a', 'b', 'c'], 'd')
print(apple)
other tests:
apple = search_for_string(['a', 'b', 'c'], 'b')
apple = search_for_string([], 'b')
Python makes your life super easy for this sort of thing:
def search_for_string(a_list, search_term):
if search_term in a_list:
return 'string found!'
return 'string not found'
There are few things wrong and Non-Pythonic in your code:
def search_for_string2(a_list, search_term):
i=0 # <----- Not Pythonic! If you want to get index we use enumerate(a_list)
for search_term in a_list: # <--- search_term passed to function is lost and gets overwritten by elements in a_list.
i += 1 # <--- Not Pythonic in this context
if a_list[i] == search_term: #<--- a_list[index+1] == a_list[index]. True if consecutive elements are same else False!
return 'string found!' #<--- No WRONG!, You didn't find the string, Consecutive elements are same!
elif a_list[i] != search_term:
return 'string not found2' #<-- Consecutive elements are not same!
if len(a_list) == 0:
return 'string not found'
According to the goals you have defined you can implement it like so:
def search_for_string(alist, search_term):
if not alist:
return "List is empty"
if search_term in alist:
return "First occurence of string Found at index position: " + str(alist.index(search_term))
else:
return "String not found"
print(search_for_string(['a', 'b', 'c'], 'd'))
print(search_for_string(['a', 'b', 'c'], 'b'))
print(search_for_string([], 'b'))
Output:
String not found
First occurence of string Found at index position: 1
List is empty
The short answer is that the return for != does not do what you think it does and that lists are 0-indexed not 1-indexed. The code is actually much simpler than you think:
def search_for_string(haystack, needle):
if not haystack: # check for empty list
return 'List was empty!'
for x in haystack:
if needle == x:
return 'String found!'
return 'String not found!'
Essentially, you only know if a string was not found if you’ve gone through and checked each element at least once. But you know if a string was found, well, when you find it.
Now to explain the issues with your code:
This version does not work because (1) it skips over the first element in the list and (2) it returns String not found/found only after checking the first element:
def search_for_string(a_list, search_term):
i=0
for search_term in a_list:
i += 1
if a_list[i] == search_term: # whoops this comparison checks for succeeding elements!
return 'string found!'
elif a_list[i] != search_term: # whoops this part returns even before all succeeding elements are checked.
return 'string not found2'
if len(a_list) == 0:
return 'string not found'
apple = search_for_string(['a', 'b', 'c'], 'd')
# In the list ['a', 'b', 'c']
# element [0] = 'a'
# element [1] = 'b'
# element [2] = 'c'
print(apple)
To explain a little further let’s take this step by step through your code:
# search_term == 'd'
# a_list = [ 'a', 'b', 'c' ]
i = 0 # at this point i == 0
for search_term in a_list:
# Oh no! we lost the search term that we passed into the
# function because we are using it as the loop iterator
# search_term == 'a'
i += 1 # i == 1
if a_list[i] == search_term:
# checks to see if 'b' == 'a'
return 'string found!'
elif a_list[i] != search_term:
# checks to see if 'b' != 'a'
return 'string not found!'
# and we return after one iteration of the loop.
Your second version has the same problem (1)(2), but avoids the issue where the first element is not checked.
There are lots of things wrong in your search_for_string function.
Main problem is that you're overwriting the value of the variable search_term. There are other problems as well that are causing incorrect output.
Here's a simpler version of your function and it meets all your requirements.
def search_for_string(a_list, search_item):
if(len(a_list) == 0):
return 'List is empty'
else:
for search_term in a_list:
if search_term == search_item:
return 'string found!'
return 'string not found'
You have quite a few errors in your in code. Some are important, others are not. I'll try to address them:
You're receiving the variable search_term as a function argument, but you then overwrite the value of it by using it in your for loop.
You're iterating over a_list by value, but you then attempt to use the loop variable i to iterate by index. Don't do this. You're already iterating by value, you don't need to do both.
You're trying to test if a_list is empty at the end of your function. Do at the beginning. Better yet, ditch the if statement and simply return at the end of your function. The for loop will not be run if a_list is empty.
Now, here is how I'd rewrite your function:
>>> def search_for_string(lst, key):
# only iterate by value.
for string in lst:
# we only need to test once
# if `key` is equal to the
# current string we are on.
if string == key:
return 'string found'
# no need to test if the list
# is empty. The for loop will
# never be run if it is, and
# this return statement will
# execute.
return 'string not found'
>>> search_for_string(['a', 'b', 'c'], 'd')
'string not found'
>>> search_for_string(['a', 'b', 'c'], 'b')
'string found'
>>> search_for_string([], 'b')
'string not found'
>>>
For your code, you should note that you're not searching properly. You pass in search_term, but a variable in a for x in y sets x to be equal to the value of the next item in y. So if you have for x in [1, 2, 3], the first time it runs it will set x = 1, etc. So first function will check if 'a' == 'b', which it's not, and the second function will check if 'a' == 'a', which it is--but neither is what you're looking for!
The best way to find if an item is in a list is
x in list
this will return True or False, if x is in the list or not! (don't use the variable 'list' though, it's bad practice since it shadows a built-in function).
So a more Pythonic way to do this would be
def search_for_string(a_list, search_term):
if search_term in a_list:
return 'string found!'
elif not a_list: # realistically you'd put this before here but I'm trying to mirror your code--why might you put this earlier? Because it's less costly than searching a list.
return 'empty list!'
else:
return 'string not found!'
Also note that bool([]) returns False, which is how we check if the list is empty.
To do it your way, we don't need to use index values, but you have to do a lot of extra, unnecessary work.
def search_for_string(a_list, search_term):
for index, item in enumerate(a_list):
if a_list[index] == search_term:
return 'string found!'
# what do you think the value of 'item' is here? it's equal to a_list[index]!
elif len(a_list) == 0: # again, you'd put this earlier--why make your computer do the work? it doesn't have to. Also, you could just do elif not a_list
return 'string not found'
else:
continue
return 'string not found2'
Most of the issues relevant to your code are covered in previous answers here, and the answer given by #Stephen Rauch sums up the most Pythonic approach to your problem.
There is one more thing that makes your code not do what you thing, even if all the other stuff was correct.
When you return in a function, you are effectively exiting that function.
So, effectively, using the for loop approach you've been trying, you would be only checking the first value in a_list, returning 'Found' if it met your search criteria, and returning 'Not found' if the first value did not match your search criteria, and then exiting your function.
Essentially, you'd never check beyond the first value.
First of all,
difference in your first method and second method are incrementing i before and after your if statement is executed. If you increment i first, your loop won't find the value for the first element of the list.
you are using i as an increment, but it is not necessary in python. You can just find out by using if the element is in a list.
def search_for_string(a_list, search_term):
#if a_list is empty, return False
if len(a_list) == 0:
return False
#if search_term has an element in a_list return the string
if search_term in a_list:
return "string found"
return "string not found"
I'm making a variation of Codecademy's pyglatin.py to make a translator that accepts and translates multiple words. However, I'm having trouble translating more than one word. I've been able to transfer the raw input into a list and translate the first, but I do not know how to reference the next item in the list. Any help would be greatly appreciated.
def piglatin1():
pig = 'ay'
original = raw_input('Enter a phrase:').split(' ')
L = list(original)
print L
i = iter(L)
item = i.next()
for item in L:
if len(item) > 0 and item.isalpha():
word = item.lower()
first = word
if first == "a" or first == "e" or first == "i" or first == "o" or first =="u":
new_word = word + pig
print new_word
else:
new_word = word[1:] + word[0:1] + pig
# first word translated
L = []
M = L[:]
L.append(new_word)
print L # secondary list created.
again = raw_input('Translate again? Y/N')
print again
if len(again) > 0 and again.isalpha():
second_word = again.lower()
if second_word == "y":
return piglatin()
else:
print "Okay Dokey!"
else:
print 'Letters only please!'
return piglatin1()
I was working on this problem recently as well and came up with the following solution (rather than use range, use enumerate to get the index).
for index, item in enumerate(L):
next = index + 1
if next < len(L):
print index, item, next
This example shows how to access the current index, the current item, and then the next item in the list (if it exists in the bounds of the list).
Here are a few things to note that might help.
The lines i = iter(L) and item = i.next() are unnecessary. They have no effect in this method because you are redefining item immediately afterwards in the line for item in L. Go ahead and comment out those two lines to see if it makes any changes in your output.
The looping construct for item in L will go once over every item in the list. Whatever code you write within this loop will be executed once for each item in the list. The variable item is your handle to the list element of an iteration.
If, during any iteration, you really do want to access the "next" element in the list as well, then consider using a looping construct such as for i in range(0,len(L)). Then L[i] will be the current item and L[i+1] will you give the subsequent item.
There are some slight issues with the code but I think there is one main reason why it will not repeat.
In order to process the entire string the
again = raw_input('Translate again? Y/N')
and it's succeeding lines should be brought outside the for statement.
Also you appear to be setting L to an empty string inside the loop:
L = []
The following is a modified version of your code which will loop through the entire sentence and then ask for another one.
def piglatin():
pig = 'ay'
while True:
L = raw_input('Enter a phrase:').split(' ')
M = []
for item in L:
if len(item) > 0 and item.isalpha():
word = item.lower()
first = word
if first == "a" or first == "e" or first == "i" or first == "o" or first =="u":
new_word = word + pig
print new_word
else:
new_word = word[1:] + word[0:1] + pig
M.append(new_word)
else:
print 'Letters only please!'
print M # secondary list created.
again = raw_input('Translate again? Y/N')
print again
if len(again) > 0 and again.isalpha():
second_word = again.lower()
if second_word == "n":
print "Okay Dokey!"
break
Changes made:
You don't need to cast the return of the split to a list. The split
return type is a list.
It isn't necessary to make an iterator, the for loop will do this for you.
I removed the function as the return type. I'm assuming you were attempting some form of recursion but it isn't strictly necessary.
Hope this helps.
Step by step:
If you set variable original in this way:
original = raw_input('Enter a phrase:').split()
it will be already a list, so need to additional assignment.
What is the purpose of these lines?
i = iter(L)
item = i.next()
In a loop, you assign variable to the word, when it is actually only the first letter of the word, so it’ll be better like this: first = word[0]
Then if you want to check if first is a vowel, you can just do:
if first in 'aeuoiy'
Answer to your actual question: do not assign L to an empty list!
If you want to repeat the action of a function, you can just call it again, no need to rewrite the code.