I am implementing a method in my python program that checks if a mathematical function is valid.
An example of one in my program would be:
['set',['tuple',1,2],['tuple',3,4]]
Which equates to, {(1,2),(3,4)}
For the check to return True all tuples within the set must have a unique number as their leftmost value. So the function {(1,2),(1,4)} would return false.
Currently I have implemented this for a set with one tuple, which would require no check for a unique value in the tuple:
if "set" in argument:
print("Found a set")
print("Next part of argument", argument[1])
if "tuple" in argument[1]:
print("Found a tuple, only one found so this argument is a function")
I am unsure how to implement this for a set that may contain multiple tuples like the examples above.
How about this:
def is_function(thing):
if thing[0] == 'set':
different = len(set(element[1] for element in thing if element[0] == 'tuple'))
tuples = sum(1 for element in thing if element[0] == 'tuple')
return different == tuples
If the first element is 'set', then count the number of different first items in the tuples (by measuring the length of its set), and compare it with the amount of "tuples" in the list.
>>> is_function(['set',['tuple',1,2],['tuple',3,4]])
True
>>> is_function(['set',['tuple',1,2],['tuple',1,4]])
False
Better explanation:
The function first tests whether the first element of the list is "set", if it's not the function terminates (and returns None).
A set is created from the generator comprehension element[1] for element in thing if element[0] == 'tuple', which will be the set of all second elements of all those lists in the main list that have a first element called "tuple". This set will contain all first values, each of them once (because it's a set).
The cardinality of that set is stored in different. It is the amount of different elements directly after "tuple".
A sum is calculated from a similar generator comprehension. Again, this iterates over all sublists whose first element is "tuple", but what is added up is just the number 1, therefore the result will be the amount of sublists that start with "tuple".
The function returns the result of different == tuples; so True if they're the same and False otherwise. If there are several "tuples" with the same starting element, then different will be smaller than tuples, so it will return False. If there aren't, it will return True, because the number of "tuples" with different starting elements will be the same as the number of "tuples".
Related
I have been reading the Core Python programming book, and the author shows an example like:
(4, 5) < (3, 5) # Equals false
So, I'm wondering, how/why does it equal false? How does python compare these two tuples?
Btw, it's not explained in the book.
Tuples are compared position by position:
the first item of the first tuple is compared to the first item of the second tuple; if they are not equal (i.e. the first is greater or smaller than the second) then that's the result of the comparison, else the second item is considered, then the third and so on.
See Common Sequence Operations:
Sequences of the same type also support comparisons. In particular, tuples and lists are compared lexicographically by comparing corresponding elements. This means that to compare equal, every element must compare equal and the two sequences must be of the same type and have the same length.
Also Value Comparisons for further details:
Lexicographical comparison between built-in collections works as follows:
For two collections to compare equal, they must be of the same type, have the same length, and each pair of corresponding elements must compare equal (for example, [1,2] == (1,2) is false because the type is not the same).
Collections that support order comparison are ordered the same as their first unequal elements (for example, [1,2,x] <= [1,2,y] has the same value as x <= y). If a corresponding element does not exist, the shorter collection is ordered first (for example, [1,2] < [1,2,3] is true).
If not equal, the sequences are ordered the same as their first differing elements. For example, cmp([1,2,x], [1,2,y]) returns the same as cmp(x,y). If the corresponding element does not exist, the shorter sequence is considered smaller (for example, [1,2] < [1,2,3] returns True).
Note 1: < and > do not mean "smaller than" and "greater than" but "is before" and "is after": so (0, 1) "is before" (1, 0).
Note 2: tuples must not be considered as vectors in a n-dimensional space, compared according to their length.
Note 3: referring to question https://stackoverflow.com/questions/36911617/python-2-tuple-comparison: do not think that a tuple is "greater" than another only if any element of the first is greater than the corresponding one in the second.
The Python documentation does explain it.
Tuples and lists are compared
lexicographically using comparison of
corresponding elements. This means
that to compare equal, each element
must compare equal and the two
sequences must be of the same type and
have the same length.
The python 2.5 documentation explains it well.
Tuples and lists are compared lexicographically using comparison of corresponding elements. This means that to compare equal, each element must compare equal and the two sequences must be of the same type and have the same length.
If not equal, the sequences are ordered the same as their first differing elements. For example, cmp([1,2,x], [1,2,y]) returns the same as cmp(x,y). If the corresponding element does not exist, the shorter sequence is ordered first (for example, [1,2] < [1,2,3]).
Unfortunately that page seems to have disappeared in the documentation for more recent versions.
I had some confusion before regarding integer comparsion, so I will explain it to be more beginner friendly with an example
a = ('A','B','C') # see it as the string "ABC"
b = ('A','B','D')
A is converted to its corresponding ASCII ord('A') #65 same for other elements
So,
>> a>b # True
you can think of it as comparing between string (It is exactly, actually)
the same thing goes for integers too.
x = (1,2,2) # see it the string "123"
y = (1,2,3)
x > y # False
because (1 is not greater than 1, move to the next, 2 is not greater than 2, move to the next 2 is less than three -lexicographically -)
The key point is mentioned in the answer above
think of it as an element is before another alphabetically not element is greater than an element and in this case consider all the tuple elements as one string.
I have been reading the Core Python programming book, and the author shows an example like:
(4, 5) < (3, 5) # Equals false
So, I'm wondering, how/why does it equal false? How does python compare these two tuples?
Btw, it's not explained in the book.
Tuples are compared position by position:
the first item of the first tuple is compared to the first item of the second tuple; if they are not equal (i.e. the first is greater or smaller than the second) then that's the result of the comparison, else the second item is considered, then the third and so on.
See Common Sequence Operations:
Sequences of the same type also support comparisons. In particular, tuples and lists are compared lexicographically by comparing corresponding elements. This means that to compare equal, every element must compare equal and the two sequences must be of the same type and have the same length.
Also Value Comparisons for further details:
Lexicographical comparison between built-in collections works as follows:
For two collections to compare equal, they must be of the same type, have the same length, and each pair of corresponding elements must compare equal (for example, [1,2] == (1,2) is false because the type is not the same).
Collections that support order comparison are ordered the same as their first unequal elements (for example, [1,2,x] <= [1,2,y] has the same value as x <= y). If a corresponding element does not exist, the shorter collection is ordered first (for example, [1,2] < [1,2,3] is true).
If not equal, the sequences are ordered the same as their first differing elements. For example, cmp([1,2,x], [1,2,y]) returns the same as cmp(x,y). If the corresponding element does not exist, the shorter sequence is considered smaller (for example, [1,2] < [1,2,3] returns True).
Note 1: < and > do not mean "smaller than" and "greater than" but "is before" and "is after": so (0, 1) "is before" (1, 0).
Note 2: tuples must not be considered as vectors in a n-dimensional space, compared according to their length.
Note 3: referring to question https://stackoverflow.com/questions/36911617/python-2-tuple-comparison: do not think that a tuple is "greater" than another only if any element of the first is greater than the corresponding one in the second.
The Python documentation does explain it.
Tuples and lists are compared
lexicographically using comparison of
corresponding elements. This means
that to compare equal, each element
must compare equal and the two
sequences must be of the same type and
have the same length.
The python 2.5 documentation explains it well.
Tuples and lists are compared lexicographically using comparison of corresponding elements. This means that to compare equal, each element must compare equal and the two sequences must be of the same type and have the same length.
If not equal, the sequences are ordered the same as their first differing elements. For example, cmp([1,2,x], [1,2,y]) returns the same as cmp(x,y). If the corresponding element does not exist, the shorter sequence is ordered first (for example, [1,2] < [1,2,3]).
Unfortunately that page seems to have disappeared in the documentation for more recent versions.
I had some confusion before regarding integer comparsion, so I will explain it to be more beginner friendly with an example
a = ('A','B','C') # see it as the string "ABC"
b = ('A','B','D')
A is converted to its corresponding ASCII ord('A') #65 same for other elements
So,
>> a>b # True
you can think of it as comparing between string (It is exactly, actually)
the same thing goes for integers too.
x = (1,2,2) # see it the string "123"
y = (1,2,3)
x > y # False
because (1 is not greater than 1, move to the next, 2 is not greater than 2, move to the next 2 is less than three -lexicographically -)
The key point is mentioned in the answer above
think of it as an element is before another alphabetically not element is greater than an element and in this case consider all the tuple elements as one string.
Full question: Design a recursive algorithm that will display whether it is possible to choose two integers from a list of integers such that the difference of the two equals a given value. Hint: You may wish to invoke another algorithm, (i.e., function), that accepts more parameters which performs the recursion. Submit a python function is_diff_two(values,diff) that take a list and the desired difference as a non-negative integer and returns true or false. The only functions you may use are: print, str, int, float, bool, len, list, range, abs, round, pow. We will not deduct for the use of str(), but you do not actually need it. Do not import libraries.
Keywords allowed: if, elif, else, and, or, not, return, def, assert,
Keywords not allowed: for, while, in, import.
Note that you may not use slicing(AKA colons in your indicies).
I am having trouble implementing this algorithm; I'm not sure what the base case is, how to use a helper method, or how to do the problem without using loops or python list slicing. What I currently have is a helper method called check_diff(), that takes a list as a parameter, recursively iterating through the list and appending to a new list all the possible differences between values in the original list. I was then going to call the method in the is_diff_two() method, in one line checking to see if the diff parameter is in the list - if so, it should return true, if not then false. This is what I have for my helper method thus far, but I cannot figure out how to correctly recurse through the list and get all the possible differences.
def check_diff(values):
diff_list = []
if len(values) == 1:
return diff_list
else:
diff_list.append(values[0] - check_diff(values[1]))
return values[0] - check_diff(values[1])
You can make a function that optionally takes two indices of the given list, and makes recursive calls with the second indice incremented until it is out of range, at which point make recursive calls with first indice incremented until it is out of range, at which point return False if there is no two values at the two indices found to differ by the target value, or return True if any such values are found:
def is_diff_two(values, diff, a=0, b=1):
if a == len(values):
return False
if b == len(values):
return is_diff_two(values, diff, a + 1, a + 2)
return abs(values[a] - values[b]) == diff or is_diff_two(values, diff, a, b + 1)
so that is_diff_two([2, 4, 8], 3) returns False,
and that is_diff_two([2, 4, 8], 4) returns True.
Define a recursive function named sort; it is passed any unordered list; it returns a new list (not mutating the argument) that contains every value in the argument list, but in non-descending order.
For example, calling sort([4,5,3,1,6,7,2]) would call sort recursively on the lists [4,5,3]and [1,6,7,2], returning the lists [3,4,5] and [1,2,6,7] respectively, which when merged would be return the list [1,2,3,4,5,6,7].
Note when the length of the list is even, both sublists will have the same
size; when the length of the list is odd, it is natural to divide it into two lists, the first of which has one fewer values than the second.
The function starts like this:
def sort(l):
I know how to separate l into two list, for example [4,5,3,1,6,7,2], I separate them into [4,5,3] and [1,6,7,2]. But I really don't know how to recursively sorting each half when the sort function only has one argument l.
Can someone please tell the way to do this? Thank you.
I gave it a go and it seems to work. Like TobiasR said, it's a merge sort. If you want a better explanation of how it works, I'd check out this video on merge sorts by Harvard University.
Anyway, this is the code for it:
def sort(l):
if len(l)==2:
if l[0]<l[1]:
return l #return list as it is
return l[::-1] #return reversed list
elif len(l)==1:
return l
l_1=sort(l[:len(l)//2]) # cut the list in half
l_2=sort(l[len(l)//2:])
l_out=[]
while True:
if not l_1: #check l1 isn't empty
l_out+=l_2
break;
elif not l_2: #check l2 isn't empty
l_out+=l_1
break;
if l_1[0]<l_2[0]: #put the smallest item in the list
l_out.append(l_1.pop(0))
else:
l_out.append(l_2.pop(0))
return l_out
Say I have a list x = [1, 2, 3, 4]
Is there a recursive method where i can go through the list to find the value?
I want to ultimately be able to compare a returned value in the list, (or nested list) to an arbitrary number to see it it matches.
I can think a way to do this using a for loop, but i have trouble imagining a recursive method to do the same thing. I know that I can't set a counter to keep track of my position in the list because calling the function recursively would just reset the counter every time.
I was thinking I could set my base case of the function as a comparison between the number and a list of len 1.
I just want some hints really.
This is not the way to do things in Python, but surely - you can traverse a list of lists recursively:
def findList(lst, ele):
if not lst: # base case: the list is empty
return False
elif lst[0] == ele: # check if current element is the one we're looking
return True
elif not isinstance(lst[0], list): # if current element is not a list
return findList(lst[1:], ele)
else: # if current element is a list
return findList(lst[0], ele) or findList(lst[1:], ele)
Recursive functions are idiomatic for when you have a linked list. Python lists are more like arrays. But it's still possible to handle a Python list with a recursive function -- there's no real utility, but it can be interesting as an exercise.
You start with a full list, and your base case is when the list is empty. Traverse the list by passing the list in as an argument, using x.pop() to simultaneously fetch and remove the first item in the list, evaluate the popped item, and then pass the list (now shorter) into the same function.
Edit: actually, on second thought, you would be better off not using x.pop() and instead peeking at the first value and passing the remainder in a slice. This would be grossly inefficient, because you're copying the list every time you slice, but it's better than destructively consuming the list inside your recursive function, unless that's a desired side-effect.
Well you will have two base cases:
1) You have reached the end of the list => return false.
2) Your current element is the element you are looking for => return true (or the element or its position, whatever you are interested in).
The thing you have to do all the time is check both base cases on the current element and apply the function recursively on the next element in the list if neither one of the base cases applied.