I am learning python on codecademy. It is going okay so far, however I cannot understand why my code works one way and not a different way. So here is the code I have made:
n = ["Michael", "Lieberman"]
def join_strings(words):
result = ""
for i in range(len(words)):
result += i
return result
print join_strings(n)
this code doesn't work... below is the code that is working for me...............
n = ["Michael", "Lieberman"]
def join_strings(words):
result = ""
for i in range(len(words)):
result += words[i]
return result
print join_strings(n)
my question is more regarding confusion on "words[i]", and what makes that code work vs the way I did it? thanks
In the first you are adding up the integer you loop over
n = ["Michael", "Lieberman"]
for i in range(len(n)):
result += i # i = 0 then i = 1, sum up to 1
print i # add this to see what you are adding up to your list
return result
Now, if you write:
n[0]
It will return the first element in your list n = ["Michael", "Lieberman"], then the code:
n = ["Michael", "Lieberman"]
for i in range(len(n)):
result += n[i]
return result
shall return the concatenation of what is in the list versus adding up the integer you loop over in the first code.
i will be an integer, not the word in word[] as this is what range() returns. len(words) also returns an integer which is the length or count of the words array.
You get access to the word by passing the index of the array in to word[] starting from 0 eg word[0] will be the first element of the array, word[1] will be the second.
Details about range():
http://pythoncentral.io/pythons-range-function-explained/
Details about len():
https://www.tutorialspoint.com/python/list_len.htm
Related
I'm currently learning python. There is an exercise in the book which outlines code for decoding. I followed along with this code however I keep getting back an error in the middle of the program.
Here is the code that is causing the problem:
def decode(string_for_decoding):
result = ""
for i in range(0, len(string_for_decoding)):
if string_for_decoding[i+1].isdigit():
result += string_for_decoding[i] * int(string_for_decoding[i+1])
elif string_for_decoding[i].isalpha():
result += string_for_decoding[i]
return result
string_for_decoding = input("Enter a string to decode: ")
print(decode(string_for_decoding))
Check if the index from range is larger than the number of chars in the string. It might look like this:
def decode(string_for_decoding: str):
result = ""
for i in range(0, len(string_for_decoding)):
if len(string_for_decoding) > i + 1 and string_for_decoding[i + 1].isdigit():
result += string_for_decoding[i] * int(string_for_decoding[i + 1])
elif string_for_decoding.isalpha():
result += string_for_decoding[i]
return result
print(decode(input("Enter a string to decode: ")))
You are going from 0 to len(string) and inside for loop you are trying to access index: i+1
THis is the root cause! Either:
iterate till one length less e.g. till len(string) - 1
Or use indices
inside appropriately
Moreover it is highly discouraged to use range(len(x)). You can simply iterate over any collective datatype as for i in x: If you want indices too have a look at enumerate(). And you can forget about index errors all together.
You are trying to get index i+1 which cannot be equal or greater than len(string).
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
I am trying to square the every digit in a number provided by the user. I am getting the correct output but I get an additional index at the end I'm not really sure why. I've put comments in my code to explain what I'm trying to do at every step. How do I get rid of that index on the end?
def square_digits(num):
print(num)
string_num =(str(num)) #convert the num to a string
for word in string_num: #iterate through every digit
word = int(word) #convert each digit to an int so we can square it
square_num = word * word
str_sq_num = list(str(square_num)) #create a list of those nums
for count in str_sq_num: #iterate through list to make it one number
print(count, end = "")
print(str_sq_num)
return str_sq_num
So an example number is being given 3212. I should output 9414, instead my output is 9414['4']. Another example is a number 6791, the output should be 3649811, but my output is 3649811['1'].
The problem is the way for loops work in python. The variable str_square_num is left over from the last iteration of for word in string_num.
For example, assuming your number is 12, in the first iteration str_square_num will be [1], or 1 squared. But this value is overriden in the second iteration, when it is set to [4], or 2 squared. Thus the array will always contain only the square of the last digit.
If your goal is to get the array of all indicies, try this:
def square_digits(num):
print(num)
string_num =(str(num)) #convert the num to a string
str_sq_num = []
for word in string_num: #iterate through every digit
word = int(word) #convert each digit to an int so we can square it
square_num = word * word
str_sq_num.extend(str(square_num)) #create a list of those nums
for count in str_sq_num: #iterate through list to make it one number
print(count, end = "")
print(str_sq_num)
return str_sq_num
I'm not sure exactly what you're trying to achieve here, but looking at your examples I suppose this should work:
def square_digits(num):
print(num)
string_num = (str(num))
str_sq_num = []
for word in string_num:
word = int(word)
square_num = word * word
str_sq_num.append(square_num)
for count in str_sq_num:
print(count, end = "")
return str_sq_num
Couldn't test it, but this should do it:
def square_digits(string_num):
return "".join([str(int(num)**2) for num in string_num])
I'm sort of new to python. I'm trying to go through a specific range of numbers and have python count all the palindromes in it and return them to me (total number count, not their sum). So it would count all the integers in this range and return it to me as one number.
I keep getting an invalid syntax error and I don't know what to change. Here is what I have so far:
import math
def ispal(n):
return str(n) == str(n)[::-1]
But this is basically just what we did in class.
My range of of numbers is from 171 to 115000 and I want to go through the entire range in between and including those 2 numbers and have python tell me how many numbers are palindromes. The problem is I don't know how to fit in the for loop.
I started with:
def count_pal(n):
count = 0
for i in range(n):
if i = str(n) == str(n)[::-1]:
return:
count =+ i
else:
pass
But I don't know how to put the 2 together. I have python 3.2. Can anyone please help me out? Thank you!
def num_palindromes(start, end):
count = 0
for i in range(start, end + 1):
if str(i) == str(i)[::-1]:
count += 1
return count
Or as a one liner
def num_palindromes(start, end):
return sum(str(i) == str(i)[::-1] for i in range(start, end + 1))
You're returning inside the for loop before you have a chance to increment the counter
You also don't need that empty 'else: pass' block as it does nothing.
A correct solution will return the counter at the end of the function after the loop terminates.
Something like this will work:
count = 0
for i in range(171, 115000):
if str(i) == str(i)[::-1]:
count += 1
return count
Note a few style changes:
- 4-space indentation
- no extraneous newlines
- no unnecessary coercion of i from 'True/False' to a number (which is what you get in your code when you do i = str(i) == str(i)[::-1])
Not directly related to your question but following python conventional style will help make your code more readable and easier for others to understand and help you with.
Lastly, just as n extra tidbit, you can also accomplish this task with a list comprehension:
sum([1 for i in range(171, 115000) if str(i) == str(i)[::-1]])
I personally find it more concise/easier to understand than the loop counter variation.
I don't know what I did - it's wrong .
Can someone help me?
def insert_sequence(dna1, dna2, number):
'''(str, str, int) -> str
Return the DNA sequence obtained by inserting the second DNA sequence
at the given index. (You can assume that the index is valid.)
>>> insert_sequence('CCGG', 'AT', 2)
'CCATGG'
>>> insert_sequence('TTGC', 'GG', 2)
'TTGGGC'
'''
index = 0
result = '';
for string in dna1:
if index == number:
result = result + dna2
result = result + string
index += 1
print(result)
Here's a solution:
def insert_sequence(dna1, dna2, number):
'''(str, str, int) -> str
Return the DNA sequence obtained by inserting the second DNA sequence
at the given index. (You can assume that the index is valid.)
>>> insert_sequence('CCGG', 'AT', 2)
'CCATGG'
>>> insert_sequence('TTGC', 'GG', 2)
'TTGGGC'
'''
return dna1[:number] + dna2 + dna1[number:]
you needed an if-else loop here :
def insert_sequence(dna1, dna2, number):
result = '';
#you can use enumerate() to keep track of index you're on
for ind,x in enumerate(dna1):
if ind == number: #if index is equal to number then do this
result = result + dna2 +x
else: #otherwise do this
result = result + x
print(result)
insert_sequence('CCGG', 'AT', 2)
insert_sequence('TTGC', 'GG', 2)
output:
CCATGG
TTGGGC
There are already right working functions in other answers (specially the comment from Rakesh Pandit and the answer from JeffS), but your actual question is "why my original function doesn't work".
I copied a working version of your function, comments below:
def insert_sequence(dna1, dna2, number):
index = 0
result = ''
for character in dna1:
if index == number:
result = result + dna2
result = result + character
index += 1
print(result)
Python considers indentation, so you should print only at the end of things, outside loops and ifs.
When you "increase" your result, you do this only inside the "if" on your function, when actually you should increase "for every character in dna1", and only when/"if index == number" you should put the middle string inside.
I believe you are very new to Python or to programming in general, being probably from a biological background, but you really shouldn't iterate to get this type of string operation done, as others have shown.
Hope this helps!
You're never splitting the string apart, so you'll always prepend dna2 to dna1.
You probably want to return dna1[:number] + dna2 + dna1[number:]
You do nothing if the index is not at the insertion point, including incrementing the index. Your code needs an else and you are also printing prematurely:
def insert_sequence(dna1, dna2, number):
index = 0
result = '';
for char in dna1:
if index == number:
result = result + dna2
result = result + char
index += len(dna2) + 1
else:
result = result + char
index += 1
print(result)
mistakes made: a) parameter index is initialised to 0. b) "for sting in dia1:" should have been "for dia1_position in range(len(dia1)):" c) print result indentation is wrong and function isn't just supposed to print. It should return result. d) index need not be incremented now.
Answers are already there. Above briefly lists the mistakes made. I guess you didn't see any error because you never called the function. First error should be "number" not defined (not any more as question has been updated and parameter has number defined).