I have recently started learning Python in the MIT class on edX.
However, I have been having some trouble with certain exercises. Here is one of them:
"Write a procedure called oddTuples, which takes a tuple as input, and returns a new tuple as output, where every other element of the input tuple is copied, starting with the first one. So if test is the tuple ('I', 'am', 'a', 'test', 'tuple'), then evaluating oddTuples on this input would return the tuple ('I', 'a', 'tuple'). "
The correct code, according to the lecture, is the following:
def oddTuples(aTup):
'''
aTup: a tuple
returns: tuple, every other element of aTup.
'''
# a placeholder to gather our response
rTup = ()
index = 0
# Idea: Iterate over the elements in aTup, counting by 2
# (every other element) and adding that element to
# the result
while index < len(aTup):
rTup += (aTup[index],)
index += 2
return rTup
However, I have tried to solve it myself in a different way with the following code:
def oddTuples(aTup):
'''
aTup: a tuple
returns: tuple, every other element of aTup.
'''
# Your Code Here
bTup=()
i=0
for i in (0,len(aTup)-1):
if i%2==0:
bTup=bTup+(aTup[i],)
print(bTup)
print(i)
i+=1
return bTup
However, my solution does not work and I am unable to understand why (I think it should do essentially the same thing as the code the tutors provide).
I just like to add that the pythonic solution for this problem uses slices with a stepwidth and is:
newTuple = oldTuple[::2]
oldTuple[::2] has the meaning: Get copy of oldtuple from start (value is omitted) to end (omitted) with a spepwidth of 2.
I think I get the problem here.
In your for loop you specify two fixed values for i:
0
len(aTup)-1
Want you really want is the range of values from 0 to len(aTup)-1:
0
1
2
...
len(aTup)-1
In order to convert start and end values into all values in a range you need to use Python's range method:
for i in range(0,len(aTup)-1):
(Actually if you take a look into range's documentation, you will find out there is a third parameter called skip. If you use it your function becomes kind of irrelevant :))
Your code should read:
for i in range(0,len(aTup)):
# i=0, 1, 2 ..., len(aTup)-1.
rather than
for i in (0,len(aTup)-1):
# i=0 or i=len(aTup)-1.
The lines for i in (0,len(aTup)-1): and i+=1 aren't quite doing what you want. As in other answers, you probably want for i in range(0,len(aTup)-1): (insert range), but you also want to remove i+=1, since the for-in construct sets the value of i to each of the items in the iterable in turn.
Okay when running your code the output is the following:
('I', 'tuple')
This is because the problem in the code you wrote is the way you implement the for loop.
Instead of using:
for i in (0,len(aTup)-1):
You should change that to the following and your code will work:
for i in range(len(aTup)):
the range function basically creates a list of integers ranging from 0 to the length of your tuple - 1.
So your code should after editing it should look like:
def oddTuples(aTup):
bTup=()
for i in range(len(aTup)):
if i%2==0:
bTup=bTup+(aTup[i],)
return bTup
Related
I'm new to python and just starting to learn the basics.
I have defined a function recursively and I want to print a list of function outputs.
This is the code:
def x(n):
assert n>=0, "Only non-negative integers n are allowed"
if n == 0:
return 5
else:
return (x(n-1)+5)/x(n-1)
print([x(0),x(1),x(2)])
for k in range(0,9,1):
print(x(k))
So my question is: say I want to print a list of the first 10 outputs of the sequence/function, i.e. x(0),...,x(9), how do I do this without actually listing each output manually? I want them to be in the form "[x(0),...,x(9)]", just like I did for the first 3 values. My attempt is in the last command of the program, where k moves from 0 to 9. The last command clearly prints the first 10 outputs, but not as a list, i.e. in [] brackets.
Any input is greatly appreciated.
One Solution:
I replaced the code
for k in range(0,9,1):
print(x(k))
with
print([x(k) for k in range(9)])
This puts the outputs in a list, i.e. in the [ ] brackets. Worked wonderfully!
You can use list comprehension.
print([x(n) for n in range(9)])
# outputs: [5, 2.0, 3.5, 2.4285714285714284, 3.058823529411765, 2.634615384615384, 2.8978102189781025, 2.72544080604534, 2.83456561922366]
Explanation:
We're making a list out by calling the function x() for each of the numbers (n) that are in the range from 0 to 9 (not included).
Please note that it is implicit that the starting point of the range() function is 0, that the step is 1, and the endpoint (9) is not included.
Here's a solution for a beginner (not an one-liner, should be easier to understand):
myarray = []
for i in range(9):
myarray.append(x(i))
Just to show the alternative to a list comprehension using map, since this is practically the scenario that map was made for:
xs = map(x, range(9))
map takes a function, and applies it to each member of the supplied iterable.
The main difference between this and using a comprehension is this returns a lazy iterable (a map object), not a list. x will not be applied to an element until you request the element.
Use of a list comprehension/generator expression is preferable in the majority of scenarios, but map is nice if you need/can tolerate a lazy result, and you already have a predefined function.
n = int(input())
numb = input()
lis = list(map(int, numb.split()))
lis.sort()
a = lis[n]
for i in (0,len(lis)):
if lis[i]=[a]
print (lis[i-1])
I tried this and when I enter input of 5 for n and the lis as 24689 it says there is an error in the line where a=lis[n] saying the list index is out of range.
The problem is probably with the line
for i in (0,len(lis)):
Lists are zero-based so the valid indexes are from 0 to len(lis) - 1. len(lis) is indeed out of range.
Also, notice that the above line of code means that i will receive only 2 values - 0 and len(lis). Is that what you really mean? If you meant to go over all the indexes, you will need to do
for i in range(len(lis)):
range(n) is an iterator that returns the values from 0 to n - 1.
There are several problems with this code. Firstly, you need to change your for statement to for i in range(0, len(lis)) because you're not currently calling the range function.
Also, on the first iteration, it will try to access index -1, which is the last element in the list. A better idea is to change your range function to range(0, len(lis) - 1), and changing the print statement on the last line to print(lis[i]) to fix the problem of receiving the last element by using the index -1.
P.S. Welcome to Stack Overflow!
Wow, Keep note that what you thought would happen on your third line wasn't the case and is 1 of the 2 problems of your error message. and that 1 problem was due to one single function you used which I have sequentially demonstration below;
I assume you were expecting each character of the string '24689' to be transformed to an integer by the map() function*, then converted to a list by the list() function*, then stored in the Variable ...lis... for later further usage. You were expecting something like [2,4,6,8,9] as Lis`.
Well you almost had that if not for your decision to use split() on Numb.
The Split function will run first and turn the '24689' into a
different iterable, in this case changing '24689' to a list ['24689'].
Then the map() will map every item in this iterable ['24689'] to an
integer. In this case only 1 item exist in the list which is '24689'.
So it maps that item as an integer.
Then the list() function stores this single item which is now an
integer in a list owned by the variable Lis. So you finally get
[24689]. And this is different from your [2,4,6,8,9] expectation.
As I've demonstrated above, so the cause of all this problem was your decision to use Split().
if you take away the split(), then;
the map() will no longer see just one Item but rather '2' '4' '6' '8'
'9' because a string '24689' is an iterable, with 5 individual items in
your case. So the map() runs over all these 5 items in your Numb string and
maps/transforms them to individual integers respectively. Then finally
the List() would have stored all these beautiful individual integers
in a list Owned by the variable Lis.And you get your desired [2,4,6,8,9] in return for the Variable Lis.
So the correct statement for that very line is:
lis = list(map(int, numb)) // This line should now produce [2,4,6,8,9]
The second problem of your error was the value you assigned to the index variable 'n' of list[n]. I assume you wanted to fetch the fifth item in the list. This 'n' is the linear count of items(in your case the individual numbers - 2,4,6,8,9). This counting start from 0 for the first letter instead of 1. Normally when you count items, the first letter is 1 but for index count in python list[n], the first letter is 0 instead of 1 so in your case the fifth item will be indexed as 4 since index count start from 0. So your 'n' input should be 4
These 2 solutions above solves your the specific error you mentioned.
BUT aside from your question above, your entire code will still run into another error even if the above solutions are implemented. This is Due to errors on these following lines as well:
On line 6:
for i in (0,len(lis)): //Wrong due to NO function name called before '(0, len(lis))'.
We will logically assume you want to use the range function
correct expression on LINE 6 is:
for i in range(0, len(lis)):
On Line 7:
if lis[i]=[a] //Three problems on this line...
First, you can't compare two objects with the operator '='. instead use '=='
Second, [a] is a meaningless value in your expression... Does comparing that to a number look right to you? I bet No. Remember [a] is not the same as the variable 'a'.
a = lis[n], while [a] = [lis[n]]
So the correct expression there should be 'a' and not '[a]'
Last, you need to add ':' after every "if", "for" or "while" expression..
Here is how LINE 7 should CORRECTLY look like,
if lis[i] == a:
All the above solutions should satisfy your need. So the complete correct code for your script should look like this:
n = int(input())
numb = input()
lis = list(map(int, numb))
lis.sort()
a = lis[n]
for i in range(0,len(lis)):
if lis[i] == a:
print (lis[i-1])
Here is a practice interview question and the correct answer below it that fulfills the question. The problem is that I don't see how this function works. I explain my confusion below the answer.
Given an array a that contains only numbers in the range from 1 to
a.length, find the first duplicate number for which the second
occurrence has the minimal index. In other words, if there are more
than 1 duplicated numbers, return the number for which the second
occurrence has a smaller index than the second occurrence of the other
number does. If there are no such elements, return -1.
Answer:
def firstDuplicate(a):
oldies={}
notfound=True
for i in range(len(a)):
try:
if oldies[a[i]]==a[i]:
notfound=False
return a[i]
except:
oldies[a[i]]=a[i]
if notfound:
return -1
So the function creates an empty dict, oldies. But then within the for loop, I don't understand how this line works:
if oldies[a[i]]==a[i]:
To me it appears that the == operator compares the indexed values of an empty dict, "oldies," to the argument that would be a list like this, for example:
a = [2, 4, 1, 3, 4, 5, 1, 5, 7, 8, 2, 4,]
But obviously "oldies" is not empty when this comparison is done. What's going on here?
I'm going to break down that answer and explain a number of the issues with it.
Explanation
Firstly, the function creates an empty dict and a boolean. Then it iterates through a range from 0 to n, which represents the length of the input list. From there it will try to compare the value at index i in the list with a value from the dictionary, which is initially empty. Since there is no proper key in the dictionary, it will throw an KeyError. This will be caught by the except statement and add to dictionary. If the first value in the input list is 'a', then the dict will now look like {'a': 'a'}. Assuming that 'a' appears later in the list, it will eventually catch find and return that value. If it finds no duplicates, it returns -1.
Issues
It is not necessary to iterate over a range to iterate over a list. Iterating over the list directly will not require checking it's length or creating a range object, so it will likely be more performant.
Creating the boolean at the beginning and using it at the end is redundant because any call to return will exit the function immediately. Therefore, if a duplicate is found the return in the if block will exit and nothing after the loop will be called.
Using a dictionary is a bad choice of structure. There is more overhead space because it needs to maintain keys, values, and their relationships. Something like a set, or even a list would be a much better choice.
Assuming we change oldies to be a set and are iterating over the list directly, the whole conditional block in that code could be reduced to a simple in statement. This also eliminates the final conditional, as mentioned above, by proper use of return.
Even though I'm advising not to use it in this case, the except block should
catch explicit exceptions instead of a general catchall. Something like except KeyError: should have been used.
The end result would look something like:
def firstDuplicate(a):
oldies = set()
for i in a:
if i in oldies:
return i
else:
oldies.add(i)
return -1
print(firstDuplicate(['a', 'b', 'c', 'b', 'a', 'c']))
Result: b
There may be some even better solutions out there using itertools or some other package.
Here's my code
def abc(l,z):
L=[]
länge= len(L)
for x in range(0, länge+1):
L[x]+z
print(L)
abc(["1","2","3"],"-")
I want the program to output "1-2-3"
l in abc(l,z) should be a List out of Strings which combines "l" and "z" to a single String.
I'm getting an Index Error: list index out of range.
There are a couple of issues here.
First, range(0, länge+1) will stop at länge but your list only has indexes from 0 tolänge - 1, so that's one source for an IndexError.
Second, L[x]+z will give you another IndexError because L is empty but you try to access L[0] (and in the next iteration, where you don't get because of the error, L[1], L[2], and so on).
Third, even without an IndexError the statement L[x]+z will do nothing. You compute the value of L[x]+z but then you don't assign any variable to it, so it is immediately lost.
Fourth, in order to print your final result, put the call to print after the for loop, not inside. Consider using return instead of print if you actually want to do something with the result the function produces (make sure to educate yourself on the difference between print and return).
Fifth, you want to build a string, so the usage of the list L does not make much sense. Start with an empty string and add the current item from l and z to it in the loop body (coupled with a re-assignment in order to not lose the freshly computed value).
Lastly, there's no point in using range here. You can iterate over values in a list direclty by simply writing for x in l:.
That should give you enough to work with and fix your code for now.
(If you don't care why your function does not work and this is not an exercise, simply use str.join as suggested in the comments.)
Hi i have the following code:
m= list()
for i in range (1,6):
set = base.Getentity(constants.ABAQUS,"SET",i)
m.append(set)
print(set)
and my result is
<Entity:0*17a:id:1>
<Entity:0*14g:id:2>
<Entity:0*14f:id:3>
<Entity:0*14a:id:4>
None
None
Here i have four elemnts in my set named set. Even though my code is written in ansa python, my question is very General
I would like to write a code which goes through the set and prints the last elemnt in my case
'<Entity:0*17a:id:4>'.
and aslo i dont want to use the range function so pls help me with writing the code.
I suggest you look at Iterators, that will help you loop through the list
If you don't want to use the range function, you can use xrange. It returns an xrange object, which is kind of like an iterator and generates the numbers on demand.
You are getting None as the last two values because there are no 'set' with the id 5 and 6 in your model
Use a filter before appending to the list m
m= list()
for i in range (1,6)
set = base.Getentity(constants.ABAQUS,"SET",i)
if set!=None:
m.append(set)
Now you can just call m[-1] for the last entity
hope this helps